📄 q.c
字号:
/*本程序是为电镀电源中的MSP430F135设计的.在本程序中不能设置本机号码,本机号码由TMS320LF2407预先设置并传递过来.
没有收到的机号不预设显示空间,只是按接收的顺序显示*/
#include <msp430x14x.h>
char status=10,Dot=0;//状态初始值为10,小数点的个数初始值为0
char BootChar1=0,BootChar2=0;//接收到的引导字符的计数器
char NISP=0;//表示处于何种接收状态
char bytes=0;
char m1=0,m2=0,m3=0,m4=0,m5;
char keybuf=0;//键值
char SendTimes=0;
int VH=0,VL=0;//电压设定值的中间结果
unsigned int Value=0;//电流设定值的中间结果
unsigned int k=0;
char Parameter[6]={0xf0,0,0,0,0,0x65};
//Parameter[0],Parameter[1],Parameter[2]是引导位.Parameter[3]是工作模式.Parameter[4],
//Parameter[5]分别为设定值的高8位和低8位.Parameter[6]是机器号,缺省为0x65.
char Add[4]={0x80,0x90,0x88,0x98};
char *p0=Add;
char *p1,*p2,*p3;
char string[6][64]={"机号: ( ) 电压: 0V 电流: 0A 总电流: 0A ",//string[0]主页.
"稳流设定:0A 稳压设定:0V ",//string[1]第二页
" ",//string[2]第三页
" ",//string[3]第四页
" ",//string[4]第五页
" "};//string[5]第六页
void delay(y)//延时子程序
{
while(y--);//while(y!=0)y--;
}
void IO_init()/*I/O初始化子程序*/
{
P1DIR=0xff;//把P1设为输出方式,
P1OUT=0x00;//且P1口设的输出为低电平
P1DIR=0x07;//将P1口的低3位设为输出方式,p1.2=RS,P1.1=RW,P1.0=E,其余各位为输入方式,
P2DIR=0xff;//设p2为输出方式
P4DIR=0xff;//设p4为输出方式
P5DIR=0x0f;//设P5的低4位设为输出,高4位设为输入
P6DIR=0xff;//将P6口设为传送的数据口(输出方式
P6OUT=0x0; //且P6口输出低电平
}
void wait_free() //等待液晶显示器完成操作的子程序
{
P6DIR=0x00; //设为输入方式
P1OUT&=~0x04; //设置RS=0
P1OUT|=0X02;//设置RW=1
P1OUT|=0X01;//设置使能E=1
while(P6IN&0x80);//如果最高位BF=1则无限执行下去。直到最高位为零
P1OUT&=~0x01;//设置使能E=0
P1OUT&=~0x04;//设置RS=0
P1OUT&=~0x02;//设置RW=1
P6DIR=0xff;//设为输出方式
}
void write_command(Command)//写命令子程序
{
wait_free();
P1OUT&=~0x04;//把RS 设置为0
P1OUT&=~0x02;//把RW设置为0
P1OUT|=0x01;//设置E=1
P6OUT=Command;//把命令字送入p6口
P1OUT&=~0x01;//把E变为=0
}
void write_data(Data)//写数据子程序
{
wait_free();
P1OUT|=0x04;//设置RS=1,数据操作
P1OUT&=~0x02;//设置RW=0,写操作
P1OUT|=0X01;//设置E=1,使能操作
P6OUT=Data;//传送数据
P1OUT&=~0x01;//设置E=0
}
void LCM_init()//液晶显示器初始化子程序
{
delay(500);
write_command(0x30);
delay(5);
write_command(0x30);
delay(5);
write_command(0x0c);
delay(5);
write_command(0x01);
delay(500);
write_command(0x06);
}
void SPI_init()//SPI通信初始化子程序
{
UCTL0&=~SWRST;//SWRST复位,USART允许
UCTL0=CHAR+SYNC;//8位数据,SPI从机模式
UTCTL0=0x02;//选外部时钟UCLK,4线模式//3线模式:UTCTL0=0x02,P3SEL|=0x0e,P3DIR=0x05
P3SEL|=0x0f;//P3.0--P3.3为模块占用
P3DIR=0x04;//P3.2(SOMI)设为输出模式,P3.3(UCLK)设为输入模式
ME1=USPIE0;//SPI0模块发送与接收允许
IE1|=URXIE0;//接收中断允许
}
unsigned char keyxd()//判断有无键被按下的子程序
{
unsigned char x;
P5OUT=0x0f;
x=(P5IN&0xf0);
return(x);
}
unsigned char key_scan()//键盘扫描子程序
{
unsigned char x;
P5OUT=0x01;//扫描第一行
if((P5IN&0xf0)==0x10)//0x0f=0x0f
x=0x0f;//第一行第一列的键被按下,键值为0;
else if((P5IN&0xf0)==0x20)
x=0x0e;//第一行第二列的键被按下,键值为1;
else if((P5IN&0xf0)==0x40)
x=0x30;//第一行第三列的键被按下,键值为2;
else if((P5IN&0xf0)==0x80)
x=0x2e;//第一行第四列的键被按下,键值为3;0x2e是小数点的ASCII码
else
{
P5OUT=0x02;//扫描第二行
if((P5IN&0xf0)==0x10)//0X0f与0Xf等价
x=0x0c;//第一行第一列的键被按下,键值为4;
else if((P5IN&0xf0)==0x20)
x=0x39;//第二行第二列的键被按下,键值为5;
else if((P5IN&0xf0)==0x40)
x=0x38;//第二行第三列的键被按下,键值为6;
else if((P5IN&0xf0)==0x80)
x=0x37;//第二行第四列的键被按下,键值为7;
else
{
P5OUT=0x04;//扫描第三行
if((P5IN&0xf0)==0x10)
x=0x0b;//第三行第一列的键被按下,键值为8;
else if((P5IN&0xf0)==0x20)
x=0x36;//第三行第二列的键被按下,键值为9;
else if((P5IN&0xf0)==0x40)
x=0x35;//第三行第三列的键被按下,键值为a;
else if((P5IN&0xf0)==0x80)
x=0x34;//第三行第四列的键被按下,键值为b;
else
{
P5OUT=0x08;//扫描第四行
if((P5IN&0xf0)==0x10)
x=0x0a;//第四行第一列的键被按下,键值为c;
else if((P5IN&0xf0)==0x20)
x=0x33;//第四行第二列的键被按下,键值为d;
else if((P5IN&0xf0)==0x40)
x=0x32;//第四行第三列的键被按下,键值为e;
else if((P5IN&0xf0)==0x80)
x=0x31;//第四行第四列的键被按下,键值为f;
else x=0x00;
}
}
}
return(x);
}
void Display(char *p1)//显示某一页内容的函数
{
int i,j;
for(i=0;i<4;i++)
{
write_command(*p0++);//将每一行的首地址写入液晶显示器
for(j=0;j<16;j++)
write_data(*p1++);
}
p0=Add;
}
void Pro_status10_20(void) //设置总电流值的预处理函数
{ //status=10,20时都用到这一段程序,故将其编成子程序
status=22;//进入总电流设置状态
for(p1=string[1]+9;*p1!=0x41;p1++);
//指针指向电流值的最后一位,为电流值的输入做准备
p1--;
Display(string[1]);
write_command(0x80+((p1-string[1]+1)>>1));
//比使用指令(p1-string[1])/2少近90字个节
write_command(0x0d);
}
void Pro_status22(void) //进行电流值设定操作的函数
{ //对按下的是数字键或删除键进行处理
if((keybuf>=0x30)&&(keybuf<=0x39))
{
if(string[1][14]==0x41);//电流为"xxxxxA"时,按下的数字键无效
else
{
if((string[1][9]==0x30)&&(string[1][10]==0x41))
{ //电流为"0A"时的操作
p1=string[1]+9;
*p1=keybuf;
}
else
{ //电流值不够五位时的操作
p1++;
*p1=keybuf;
*(p1+1)=0x41;//0x41是'A'的ASCII码
}
Value<<=1;//Value*10
Value=Value+(Value<<2);
Value=Value+keybuf-0x30;//计算电流指令值
}
}
else if(keybuf==0x0b)
{ // 按下的是删除键
Value=(Value+0x30-*p1)/10;//计算电流指令值
if(*(p1-1)==0x3a)
*p1=0x30;
else
{
*(p1+1)=0x20;
*p1=0x41;
p1--;
}
}
Display(string[1]);
write_command(0x80+((p1-string[1]+1)>>1));//指定光标闪烁的位置
}
void Pro_status24(void) //设置电压值的处理函数
{
if((Dot!=0)&&(keybuf==0x2e));//如果已输入一个小数点,
//此次被按下的小数点为无效操作
else
{
if((keybuf>=0x2e)&&(keybuf<=0x39))//按下的是小数点或数字键
if(string[1][45]==0x56);//电压为"xxxxV"时,按下的数字键无效
else
{
if((string[1][41]==0x30)&&(string[1][42]==0x56)&&(keybuf!=0x2e))
{ //电压为"0V"时的操作
p1=string[1]+41;
*p1=keybuf;
}
else
{ //电压值不够四位时的操作
p1++;
*p1=keybuf;
*(p1+1)=0x56;//0x56是'V的ASCII码
}
if(*p1==0x2e)Dot+=1;//如果有小数点输入,则Dot加1
if(Dot==0)
{ //VH*10
VH<<=1;
VH=VH+(VH<<2);
VH=VH+*p1-0x30;
}
if(Dot!=0)
{
if(*p1==0x2e);
else
{
VL<<=1;//VL*10
VL=VL+(VL<<2);
VL=VL+*p1-0x30;
}
}
}
else if(keybuf==0x0b)
{ //按下的是删除键
if(*(p1-1)==0x3a)
*p1=0x30,VH=0;//电压为"xV"时的操作
else
{
*(p1+1)=0x20;
if((Dot!=0)&&(*p1!=0x2e))
VL=(VL+0x30-*p1)/10;//有小数点,但删去的不是小数点
else if((Dot!=0)&&(*p1==0x2e))
Dot-=1;//如果有小数点被删除,则Dot减1
else VH=(VH+0x30-*p1)/10;//没有小数点
*p1=0x56;
p1--;
}
}
Display(string[1]);
write_command(0x78+((p1-string[1]+1)>>1));//指定光标闪烁的位置
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -