📄 main.c
字号:
/********************************************************************/
// LM240128R液晶基本显示程序
//编写:李科
//时间:2007年12月01日
//修改:2007年12月04日
//资源分配:MSP430F2274 12M内晶振
//
//P1.0:为DS18B20通讯口
//P1.1--P1.7:预留
//
//P2.0--P2.1:ADC输入转换口
//P2.2:为键盘AD采样口
//P2.3--P2.7:预留
//
//P3.0--P3.2:接74LS138控制端A B C
//P3.3--P3.7:接LM240128R液晶 /RST /RS /CS /RD /WR 端
//
//P4.0--P4.7:LCD LED数据口D0--D7共用端
/********************************************************************/
#include "msp430x22x4.h"
/**********端口宏定义**********/
#define uchar unsigned char
///////////////////////////////
/* LM240128R液晶端口宏定义 */
///////////////////////////////
#define lcd_data P4OUT //设置8位数据输入口
#define lcd_ctrl P3OUT //设置命令控制口
#define lcd_wr_port 0x80 //设置写控制口
#define lcd_rd_port 0x40 //设置读控制口
#define lcd_cs_port 0x20 //设置片选控制口
#define lcd_rs_port 0x10 //设置命令数据选择控制口
#define lcd_rst_port 0x08 //设置复位控制口
#define lcd_wr_0 lcd_ctrl&=~lcd_wr_port
#define lcd_wr_1 lcd_ctrl|=lcd_wr_port
#define lcd_rd_0 lcd_ctrl&=~lcd_rd_port
#define lcd_rd_1 lcd_ctrl|=lcd_rd_port
#define lcd_cs_0 lcd_ctrl&=~lcd_cs_port
#define lcd_cs_1 lcd_ctrl|=lcd_cs_port
#define lcd_rs_0 lcd_ctrl&=~lcd_rs_port
#define lcd_rs_1 lcd_ctrl|=lcd_rs_port
#define lcd_rst_0 lcd_ctrl&=~lcd_rst_port
#define lcd_rst_1 lcd_ctrl|=lcd_rst_port
///////////////////////////////
/* DS18B20端口宏定义 */
///////////////////////////////
#define ds18b20_dir P1DIR
#define ds18b20_out P1OUT
#define ds18b20_in P1IN
#define ds18b20_port 0x01
/***********函数申明***********/
void port_init(void);
void delay_us(unsigned int delay_us_time);
void delay_ms(unsigned int delay_ms_time);
void lcd_cmd_send(uchar lcd_command);
void lcd_data_send(uchar lcd_data_num);
void lcd_clean(void);
void lcd_text_display(uchar *text_display);
void lcd_num_display(long int num_display);
void lcd_float_display(float float_display);
void lcd_box_display(uchar f_x,uchar f_y,uchar s_x,uchar s_y,uchar draw_model);
void lcd_init(void);
void menu(void);
void timea_init(void);
void adc_init(void);
unsigned char ds18b20_ack(void);
unsigned char ds18b20_read(void);
void ds18b20_write(unsigned char cmd);
float ds18b20_single_data(void);
void ds18b20_single_rom(void);
void ds18b20_many_data(void);
void key_scan(void);
/***********全局变量***********/
float adc_num=0,adc_numx=0; //AD采样显示变量
unsigned long timea0=0,timea1=0;//时间显示变量
uchar ds18b20_rom[8];
uchar ds18b20_rom_store[2][8]={40,112,73,71,1,0,0,81,
40,240,22,71,1,0,0,65};
uchar led_code[]={0xd7,0x11,0xcd,0x5d,0x1b,0x5e,0xde,0x15,0xdf,0x5f,0x20};
uchar led_a=0,led_b=0,led_c=0,led_d=0;
unsigned long led_xs=0;
uchar xtime=0;//全局FOR循环变量
unsigned int ytime=0;
uchar key_num=0;
/**********端口初始化**********/
void port_init(void)
{
P1DIR = 0xff;//p1.0为DS18B20通讯口
P1OUT = 0xff;
P1SEL = 0x00;
P2DIR = 0xf8;//0b11111000
P2OUT = 0xf8;
P2SEL = 0x07;//p2.0 p2.1打开ADC输入 0b00000111
P3DIR = 0xff;
P3OUT = 0xff;
P3SEL = 0x00;
P4DIR = 0xff;
P4OUT = 0xff;
P4SEL = 0x00;
}
/**********us软件延时**********/
void delay_us(unsigned int delay_us_time)
{
unsigned int delay_us_x;
for(delay_us_x=0;delay_us_x<delay_us_time;delay_us_x++)
{
_NOP();_NOP();_NOP();_NOP();_NOP();_NOP();
_NOP();_NOP();_NOP();_NOP();_NOP();//12M下每个_NOP();占0.09uS
}
}
/**********ms软件延时**********/
void delay_ms(unsigned int delay_ms_time)
{
unsigned int delay_ms_x;
unsigned int delay_ms_y;
for(delay_ms_x=0;delay_ms_x<delay_ms_time;delay_ms_x++)
{
for(delay_ms_y=0;delay_ms_y<1000;delay_ms_y++)
{
_NOP();_NOP();_NOP();_NOP();_NOP();_NOP();
_NOP();_NOP();_NOP();_NOP();_NOP();
}
}
}
/**********LCD初始化**********/
void lcd_init(void)
{
lcd_rst_0; //复位
delay_ms(100);
lcd_rst_1;
delay_ms(100);
lcd_cmd_send(0x20);lcd_cmd_send(0x1d); //设置工作视窗右边位置
lcd_cmd_send(0x30);lcd_cmd_send(0x7f); //设置工作视窗底部位置
lcd_cmd_send(0x40);lcd_cmd_send(0x00); //设置工作视窗左边位置
lcd_cmd_send(0x50);lcd_cmd_send(0x00); //设置工作视窗顶部位置
lcd_cmd_send(0x21);lcd_cmd_send(0x1d); //设置显示视窗右边位置
lcd_cmd_send(0x31);lcd_cmd_send(0x7f); //设置显示视窗底部位置
lcd_cmd_send(0x41);lcd_cmd_send(0x00); //设置显示视窗左边位置
lcd_cmd_send(0x51);lcd_cmd_send(0x00); //设置显示视窗顶部位置
lcd_cmd_send(0x00);lcd_cmd_send(0xcd); //正常模式,文本,显示开,不闪烁,不反白
lcd_cmd_send(0x81);lcd_cmd_send(0x40); //参数要求
lcd_cmd_send(0x11);lcd_cmd_send(0x10); //光标高度,行距
lcd_cmd_send(0x10);lcd_cmd_send(0x68); //显示时候的基本设置
lcd_cmd_send(0x90);lcd_cmd_send(0x06); //设置时钟信号周期(刷新率,数值越小刷新越快)
lcd_cmd_send(0xf0);lcd_cmd_send(0xa0); //自动解码,可以显示中文
lcd_cmd_send(0xf1);lcd_cmd_send(0x0f); //1倍字体大小
}
/**********LCD清屏**********/
void lcd_clean(void)
{
uchar lcd_clean_x;
uchar lcd_clean_y;
lcd_cmd_send(0x60);lcd_cmd_send(0x00);
lcd_cmd_send(0x70);lcd_cmd_send(0x00);
for(lcd_clean_x=0;lcd_clean_x<30;lcd_clean_x++)
{
for(lcd_clean_y=0;lcd_clean_y<128;lcd_clean_y++)
{lcd_data_send(0x00);}
}
}
/**********LCD写命令**********/
void lcd_cmd_send(uchar lcd_command)
{
lcd_data=lcd_command;
lcd_cs_0;
lcd_rs_0;
lcd_wr_0;
delay_us(20);//极限值为15us
lcd_wr_1;
lcd_rs_1;
lcd_cs_1;
}
/**********LCD写数据**********/
void lcd_data_send(uchar lcd_data_num)
{
lcd_data=lcd_data_num;
lcd_cs_0;
lcd_rs_1;
lcd_wr_0;
delay_us(20);//极限值为15us
lcd_wr_1;
lcd_rs_0;
lcd_cs_1;
}
/**********LCD显示文本**********/
void lcd_text_display(uchar *text_display)
{
while(*text_display>0)
{
lcd_data_send(*text_display);
text_display++;
}
}
/**********LCD显示变量**********/
void lcd_num_display(long int num_display)
{
uchar a,b,c,d,e,f,g;
if(num_display<0) //显示“-”号
{
lcd_text_display("-");
num_display*=-1;
}
a=num_display/1000000;
b=num_display%1000000/100000;
c=num_display%100000/10000;
d=num_display%10000/1000;
e=num_display%1000/100;
f=num_display%100/10;
g=num_display%10;
if(num_display>=1000000)
{lcd_data_send(a+48);}
if(num_display>=100000)
{lcd_data_send(b+48);}
if(num_display>=10000)
{lcd_data_send(c+48);}
if(num_display>=1000)
{lcd_data_send(d+48);}
if(num_display>=100)
{lcd_data_send(e+48);}
if(num_display>=10)
{lcd_data_send(f+48);}
lcd_data_send(g+48);
}
/**********LCD显示浮点数**********/
void lcd_float_display(float float_display)
{
long int first_num=0;
float last_num=0;
uchar a,b,c,d;
if(float_display<0)
{
lcd_text_display("-");
float_display*=-1;
}
first_num=float_display; //取出整数部分
lcd_num_display(first_num); //显示整数部分
lcd_text_display("."); //显示小数点
last_num=float_display-first_num; //取出小数部分
first_num=last_num*10000;
a=first_num/1000;
b=first_num%1000/100;
c=first_num%100/10;
d=first_num%10;
lcd_data_send(a+48);
lcd_data_send(b+48);
lcd_data_send(c+48);
lcd_data_send(d+48);
}
/***********************************************************
* 函数说明:画矩形框工具 *
* 输入:矩框坐标 DrawModel FillColor *
* [DrawModel] [说明] *
* 0 擦除 *
* 1 画线 *
* 2 填充 *
* [FillColor] [说明] *
* 0 白 *
* 1 黑 *
* 2 反色(XOR) *
***********************************************************/
void lcd_box_display(uchar f_x,uchar f_y,uchar s_x,uchar s_y,uchar draw_model)
{
uchar x_start=0,x_flag=0,x_flag1=0,x_flag2=0;
lcd_cmd_send(0x00);lcd_cmd_send(0xc5); //正常模式,图形,显示开,不闪烁,不反白
lcd_cmd_send(0x12);lcd_cmd_send(0x83); //图层操作
if(draw_model==0)//擦除模式
{
x_start=f_x>>3; //f_x/8求模,计算起始块位置
for(x_flag1=f_y;x_flag1<=s_y;x_flag1++) //画横线
{
lcd_cmd_send(0x60);lcd_cmd_send(x_start); //起始位置定位
lcd_cmd_send(0x70);lcd_cmd_send(x_flag1);
lcd_data_send(0x00); //显示第一块的点数
x_flag=(s_x-f_x-(7-f_x%8)); //计算剩下需要显示的点数
for(x_flag2=0;x_flag2<(x_flag>>3);x_flag2++) //计算显示按块显示的块数
{lcd_data_send(0x00);}
lcd_data_send(0x00);
}
}
else if(draw_model==1)//画线模式
{
x_start=f_x>>3; //f_x/8求模,计算起始块位置
for(x_flag1=f_y+1;x_flag1<s_y;x_flag1++) //画左边竖线
{
lcd_cmd_send(0x60);lcd_cmd_send(x_start); //起始位置定位
lcd_cmd_send(0x70);lcd_cmd_send(x_flag1);
x_flag=0x80;
x_flag>>=f_x%8;
lcd_data_send(x_flag);
}
for(x_flag1=f_y;x_flag1<=s_y;x_flag1+=(s_y-f_y))//画上下横线
{
lcd_cmd_send(0x60);lcd_cmd_send(x_start); //起始位置定位
lcd_cmd_send(0x70);lcd_cmd_send(x_flag1);
x_flag=0xff;
x_flag>>=f_x%8; //求余计算第一块显示点数
lcd_data_send(x_flag); //显示第一块的点数
x_flag=(s_x-f_x-(7-f_x%8)); //计算剩下需要显示的点数
for(x_flag2=0;x_flag2<(x_flag>>3);x_flag2++) //计算显示按块显示的块数
{lcd_data_send(0xff);}
x_flag2=0xff; //计算显示最后剩下的点数
x_flag2<<=(8-x_flag%8);
lcd_data_send(x_flag2);
}
for(x_flag1=f_y+1;x_flag1<s_y;x_flag1++) //画右边竖线
{
lcd_cmd_send(0x60);lcd_cmd_send(s_x>>3); //起始位置定位
lcd_cmd_send(0x70);lcd_cmd_send(x_flag1);
x_flag2=0x01;
x_flag2<<=(8-x_flag%8);
lcd_data_send(x_flag2);
}
}
else if(draw_model==2)//填充模式
{
x_start=f_x>>3; //f_x/8求模,计算起始块位置
for(x_flag1=f_y;x_flag1<=s_y;x_flag1++) //画横线
{
lcd_cmd_send(0x60);lcd_cmd_send(x_start); //起始位置定位
lcd_cmd_send(0x70);lcd_cmd_send(x_flag1);
x_flag=0xff;
x_flag>>=f_x%8; //求余计算第一块显示点数
lcd_data_send(x_flag); //显示第一块的点数
x_flag=(s_x-f_x-(7-f_x%8)); //计算剩下需要显示的点数
for(x_flag2=0;x_flag2<(x_flag>>3);x_flag2++) //计算显示按块显示的块数
{lcd_data_send(0xff);}
x_flag2=0xff; //计算显示最后剩下的点数
x_flag2<<=(8-x_flag%8);
lcd_data_send(x_flag2);
}
}
lcd_cmd_send(0x00);lcd_cmd_send(0xcd); //正常模式,文本,显示开,不闪烁,不反白
}
/**********TimeA定时器**********/
//Clock source=SMCLK
//Divider=8
//TIMACLK=1.5000MHz
//Frequency=1.000KHz ( 1.00mS)
void timea_init(void)
{
TACTL=0x00; //控制器清0
//channel0
TACCTL0|=CCIE; //TACCIE0 捕获/比较模块允许中断
TACCR0=0x2EE; //设置寄存器0值
//channel1
TACCTL1=0x00;
TACCR1=0x00;
//channel2
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -