⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 q.c

📁 msp430单片机与dsp的同步通信及传输过程中的显示及编码
💻 C
📖 第 1 页 / 共 3 页
字号:

/*本程序是为电镀电源中的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 + -