"); //-->
这是从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
*博客内容为网友个人发布,仅代表博主个人观点,如有侵权请联系工作人员删除。