新闻  |   论坛  |   博客  |   在线研讨会
基于MSP430F149的液晶时钟显示
Capture | 2013-08-01 23:13:07    阅读:863   发布文章

这是从51单片机转到430单片机写的第一个程序,模块化编程。包括以下功能1602显示时钟,矩阵键盘扫描修改时间,通过串口通信,电脑发数据修改时间,单片机每隔一定时间向电脑发送当前时间。

液晶显示程序

1602.c文件

#include "1602.h"
/*****************************************
函数名称:Lcd_Busy
作    用:1602监测忙标志
入口参数:无
返 回 值:无
******************************************/
uchar Lcd_Busy()
{
 uchar busy; //忙标志位
 Dat_Input;
 CLR_RS;   //读标志位
 SET_RW;
 DelayUs(10);
 SET_EN;
 DelayUs(10);
 busy = (DATIN&0x80);
 CLR_EN;
        Dat_Output;
 return busy;
}

/*****************************************
函数名称:Lcd_Wr_Cmd
作    用:1602写命令函数
入口参数:uchar cmd
返 回 值:无
******************************************/
void Lcd_Wr_Cmd(uchar cmd)
{
 while(Lcd_Busy());  //检测忙标志
 CLR_RS;   //写命令
 CLR_RW;
 DAT = cmd;
 DelayUs(10);  
 SET_EN;    //上升沿写入命令
 DelayUs(10);
 CLR_EN;
}

/*****************************************
函数名称:Lcd_Wr_Dat
作    用:1602写数据函数
入口参数:uint dat
返 回 值:无
******************************************/
void Lcd_Wr_Dat(uchar dat)
{
 while(Lcd_Busy());    //检测忙标志
 SET_RS;     //写数据
 CLR_RW;
 DAT = dat;
 DelayUs(10);
 SET_EN;     //上升沿写入数据
 DelayUs(10);
 CLR_EN; 
}

/*****************************************
函数名称:Lcd_Init
作    用:1602初始化函数
入口参数:无
返 回 值:无
******************************************/
void Lcd_Init()
{
    LCD_OUT;
 CLR_EN;
 Delay_ms(10);
 Lcd_Wr_Cmd(0x38);  //选择8位数据模式   
 Delay_ms(10);
 Lcd_Wr_Cmd(0x08); //关闭显示
 Lcd_Wr_Cmd(0x01); //显示清屏
 Lcd_Wr_Cmd(0x06); //光标移动设定,指针加一
 Lcd_Wr_Cmd(0x0c); //开显示,无光标,不闪烁 
}

/*****************************************
函数名称:Lcd_Clear
作    用:1602清屏函数
入口参数:无
返 回 值:无
******************************************/
void Lcd_Clear()      
{
 Lcd_Wr_Cmd(0x01);  //显示清屏
 Delay_ms(10);
}

/*****************************************
函数名称:Lcd_Setxy
作    用:1602设定要写入的坐标
入口参数:uchar x,uchar y
返 回 值:无
******************************************/
void Lcd_Setxy(uchar x,uchar y)
{
 if(y==0)
 {
  Lcd_Wr_Cmd(0x80+x);    //第一行,0x80-0xa7
 }
 else    
 {    
  Lcd_Wr_Cmd(0xc0+x);  //第一行,0xc0-0xe7
 } 
}

/*****************************************
函数名称:Lcd_Wr_Str
作    用:1602写字符串函数,连续写入一个字符串
入口参数:uchar *p(字符串首地址)
返 回 值:无
******************************************/
void Lcd_Wr_Str(uchar x,uchar y,uchar *p)
{
 Lcd_Setxy(x,y);   //要写入字符串的起始地址
 while(*p)
 {
  Lcd_Wr_Dat(*p);  
  p++; 
 } 
}

/*****************************************
函数名称:Lcd_Wr_char
作    用:1602写字符函数
入口参数:uchar dat(要显示的字符)
返 回 值:无
******************************************/
void Lcd_Wr_char(uchar dat)
{
 Lcd_Wr_Dat(dat); 
}

/*****************************************
函数名称:Lcd_Wr_Shuzi
作    用:向1602写入一位十进制数。
入口参数:uchar 数(要显示的数)
返 回 值:无
******************************************/
void Lcd_Wr_Shuzi(uchar shu)
{
 Lcd_Wr_Dat(0x30+shu); 
}

/*****************************************
函数名称:Lcd_Wr_Time
作    用:向1602制定位置写入一个两位数。
入口参数:Clock (要显示的两位数)
返 回 值:无
******************************************/
void Lcd_Wr_Time(uchar x,uchar y,uchar Clock)
{
 uchar shi,ge;
 shi = Clock/10;
 ge = Clock%10;
 Lcd_Setxy(x,y);
 Lcd_Wr_Shuzi(shi);
 Lcd_Wr_Shuzi(ge);

/*********************************************************
函数名称:Lcd_Wr_Tab
作    用:向1602的CGRAM写入自定义字符,存储在RAM中的数。
入口参数:uchar 数(要显示的数)
返 回 值:无
*********************************************************/
void Lcd_Wr_Tab(uchar add,uchar  *p) 

    uchar i;
    Lcd_Wr_Cmd(0x40 + add*8);            //写CGRAM
    for (i = 0; i< 8; i++)
 {      
     Lcd_Wr_char(*p);
  p++;      
 }
}

1602.h头文件

 

#ifndef __1602_H__
#define __1602_H__

#include "MSP430x14x.h"
#include "delay.h"

#define uchar unsigned char
#define uint  unsigned int

//数据后定义
#define DAT P4OUT
#define DATIN P4IN
#define Dat_Input P4DIR = 0x00
#define Dat_Output P4DIR = 0xff
#define LCD_OUT  P3DIR |=0x07 

//1602控制端定义
#define RS     (0x01);  //数据命令控制位
#define RW     (0x02);  //读写控制位
#define LCDEN  (0x04);  //使能控制位

//1602控制端口高低电平控制
#define SET_RS P3OUT |= RS    
#define CLR_RS P3OUT &= ~RS
#define SET_RW P3OUT |= RW
#define CLR_RW P3OUT &= ~RW
#define SET_EN P3OUT |= LCDEN
#define CLR_EN P3OUT &= ~LCDEN

//函数声明
uchar Lcd_Busy();                          //检测忙标志
void Lcd_Wr_Cmd(uchar cmd);         //写命令函数
void Lcd_Wr_Dat(uchar cmd);         //写数据函数
void Lcd_Init();          //液晶初始化
void Lcd_Clear();          //液晶清屏
void Lcd_Setxy(uchar x,uchar y);        //设定地址
void Lcd_Wr_Str(uchar x,uchar y,uchar *p);     //往指定地址写入字符串
void Lcd_Wr_char(uchar dat);         //写数据函数
void Lcd_Wr_Shuzi(uchar shu);   //写入液晶一位十进制数字
void Lcd_Wr_Time(uchar x,uchar y,uchar Clock); //往指定地址写入一个二位十进制数
void Lcd_Wr_Tab(uchar add,uchar *p);  //往液晶CGRAM写入数据(即自定义字符串)

#endif

——————————————————————————————————————————

4*4矩阵键盘扫描程序

key.c文件

 

/*************************************************************************
文件名称:key.c
说明:矩阵键盘扫描,获得键值
接线对应IO
P2   0 1 2 3    4 5 6 7
   行4 3 2 1  列1 2 3 4
对应码值
        E7 D7 B7 77
        EB DB BB 7B
        ED DD BD 7D
        EE DE BE 7E

**************************************************************************/

#include "key.h"

uchar key;
uchar key_flag;


/*****************************************
函数名称:按键扫描
作    用:按键扫描
入口参数:无
返 回 值:无
******************************************/
uchar keyscan(void)  //键盘扫描函数,使用行列反转扫描法
{
 unsigned char cord_h,cord_l;//行列值中间变量
 P2DIR = 0XF0;
 P2OUT = 0x00;            //行线输出全为0
 if((P2IN&0x0f)!= 0x0f)    //先检测有无按键按下
 {
  Delay_ms(50);
  if((P2IN&0x0f)!= 0x0f)
  {
    cord_h = P2IN & 0x0f;  //读入行线值
 P2DIR = 0X0f;
 Delay_ms(50);      
    cord_l = P2IN & 0xf0;  //读入列线值
    return(cord_h + cord_l);//键盘最后组合码值
   }
  }return(0xff);     //返回该值
}
/*****************************************
函数名称:按键扫描键值处理
作    用:矩阵键盘扫描,获得键值
入口参数:无
返 回 值:无
******************************************/
void key_value()
{
 key = keyscan();
 switch( key )
 {
    case 0XE7 :  key_flag = 1; key = 0;  break;
  case 0XD7 :  key_flag = 2; key = 0; break;
  case 0XB7 :  key_flag = 3; key = 0; break;
     case 0X77 :  key_flag = 4; key = 0; break;
  
  case 0XEB :  key_flag = 5; key = 0; break;
  case 0XDB :  key_flag = 6; key = 0; break;
  case 0XBB :  key_flag = 7; key = 0; break;
     case 0X7B :  key_flag = 8; key = 0; break;
  
  case 0XED :  key_flag = 9; key = 0; break;
  case 0XDD :  key_flag = 10;key = 0; break;
  case 0XBD :  key_flag = 11;key = 0; break;
     case 0X7D :  key_flag = 12;key = 0; break;
  
  case 0XEE :  key_flag = 13;key = 0; break;
  case 0XDE :  key_flag = 14;key = 0; break;
  case 0XBE :  key_flag = 15;key = 0; break;
     case 0X7E :  key_flag = 16;key = 0; break;
  
 }      

}

矩阵键盘头文件

key.h

 

#ifndef __KEY_H__
#define __KEY_H__

#include "MSP430x14x.h"
#include "delay.h"
#define  uint unsigned int
#define  uchar unsigned char

 

uchar keyscan();
void key_value();


extern uchar key_flag;
extern uchar key;

#endif

——————————————————————————————————————

串口通信程序

 

/*************************************************************************
文件名称:com.c
说明:串口通信液晶模块程序 ,电脑发送数据单片机修改,
单片机每隔5S将当前年月日时分秒发送给电脑显示
**************************************************************************/
#include "com.h"
uchar g_get_flag; 

uchar g_Temp;

uchar Year_q = 2,Year_b = 0,Year_s = 1,Year_g = 3,Yue_s = 0 ,Yue_g = 7,Ri_s  = 0,Ri_g = 4,hour_s = 1,hour_g = 1,Min_s = 1 ,Min_g=1,Sec_s=1,Sec_g=1;
uchar  table[14];
uchar  time_str[21];
uint i;

uchar g_Year_1 = 20,g_Year_2 = 13,g_Yue = 7,g_Ri = 14 ,g_Hour,g_Minuter,g_second ;
/****************************************************
 * 函 数 名:Com_Init
 * 功能描述:串口初始化,设置模式1及波特率为9600
 * 输入参数:无
 * 返 回 值:无
*****************************************************/
void Com_Init()
{
    P3SEL |=0x30;                            // 选择P3.4和P3.5做UART通信端口
    ME1 |= UTXE0 + URXE0;                     // 使能USART0的发送和接受
    UCTL0 |= CHAR;                            // 选择8位字符
    UTCTL0 |= SSEL0;                         
    UBR00 = 0x03;                             // 波特率9600
    UBR10 = 0x00;                             //
    UMCTL0 = 0x4A;                            // Modulation
    UCTL0 &= ~SWRST;                          // 初始化UART状态机
    IE1 |= URXIE0;
 
}


/****************************************************
 * 函 数 名:change_time
 * 功能描述:接收电脑发过来的数据,然后转化后,送液晶显示
 * 输入参数:无
 * 返 回 值:无
*****************************************************/
void change_time()
{
    if(g_get_flag == 1)
    {
        g_get_flag = 0;
        g_Year_1 = table[0] * 10 + table[1];
        g_Year_2 = table[2] * 10 + table[3];
        g_Yue = table[4] * 10 + table[5];
        g_Ri = table[6] * 10 + table[7];
        g_Hour = table[8] * 10 + table[9];
        g_Minuter = table[10] * 10 + table[11];
        g_second = table[12] * 10 + table[13];
   
    }
   
    Lcd_Wr_Time(3,0,g_Year_1);
    DelayUs(100);
   
    Lcd_Wr_Time(5,0,g_Year_2);
    DelayUs(100);
   
    Lcd_Wr_Time(8,0,g_Yue);
    DelayUs(100);
                   
    Lcd_Wr_Time(11,0,g_Ri);
    DelayUs(100);
                           
    Lcd_Wr_Time(4,1,g_Hour);
    DelayUs(100);

    Lcd_Wr_Time(7,1,g_Minuter);
    DelayUs(100);

    Lcd_Wr_Time(10,1,g_second);
    DelayUs(100);

}

/****************************************************
 * 函 数 名:send_time
 * 功能描述:发送当前年月日时分秒的数值
 * 输入参数:无
 * 返 回 值:无
*****************************************************/
void send_time()
{
      time_str[0] = g_Year_1 / 10;  
      time_str[1] = g_Year_1 % 10;
      time_str[2] = g_Year_2 / 10;
      time_str[3] = g_Year_2 % 10;

   time_str[4] = 0X2D-0X30;   // -
  
      time_str[5] = g_Yue / 10;
      time_str[6] = g_Yue % 10;
  
   time_str[7] = 0X2D-0X30;   // -

      time_str[8] = g_Ri / 10;
      time_str[9] = g_Ri % 10;
  
   time_str[10] = 0X2D-0X30;   // -

      time_str[11] = g_Hour / 10;
      time_str[12] = g_Hour % 10;
  
   time_str[13] = 0X3A-0X30;   // :

      time_str[14] = g_Minuter / 10;
      time_str[15] = g_Minuter % 10;
  
   time_str[16] = 0X3A-0X30;   // :

      time_str[17] = g_second / 10;
      time_str[18] = g_second % 10;
  
   time_str[19] = '\r' -0x30;
   time_str[20] = '\n' -0x30;
   
      for(i = 0;i < 21;i++)
      {
  while (!(IFG1 & UTXIFG0));
        TXBUF0 = time_str[i] + 0X30;
      }
  
     

}

串口通信头文件

com.h

 

 

#ifndef __COM_H__
#define __COM_H__

#include "MSP430x14x.h"
#include "delay.h"
#include "1602.h"


#define uint unsigned int
#define uchar unsigned char

extern uchar g_Year_1 ,g_Year_2 ,g_Yue,g_Ri  ,g_Hour,g_Minuter,g_second ;
extern uchar g_get_flag;//定义全局变量 g_get_flag SBUF接收寄存器接受完所有数据后,g_get_flag标志位置1

extern uchar g_Temp; //全局变量,接受寄存器接收的数据赋值给 Temp
extern uchar  table[14];

extern uchar  time_str[21];//数组存放单片机发送的数值

void  Com_Init();                //串口初始化
void  change_time();//接收电脑发过来的数据,然后转化后,送液晶显示
void  send_time();  //发送当前年月日时分秒的数值


#endif

 

 

 

*博客内容为网友个人发布,仅代表博主个人观点,如有侵权请联系工作人员删除。

参与讨论
登录后参与讨论
推荐文章
最近访客