MSP做一个单通道的ADC,然后在LCD12864上串行输出显示,然后就一直没有显示

2019-03-24 12:31发布

  1. 我自己的感觉,首先是ADC没有成功。。。但是LCD显示的也不对啊。


  2. 接口定义如下:
  3. //sbit CS=P1^0; //接口定义sbit SCLK=P1^2;sbit STD=P1^1;//


  4. #include  
  5. #define uchar unsigned char
  6. #define uint unsigned int
  7.   double data;//用来存储ADC12MEM中的数据
  8.   char a,b,c=0; //用来存储将要显示在LCD上的各位数据

  9. //初始化时钟
  10. void initClock(void){
  11.   BCSCTL1=RSEL2+RSEL1+RSEL0+DIVA_1;//XT2开启 LFXT1工作在低频模式 ACLK 2分频( 注释:原来的人没做分频,我担心频率过高) 最高的标称频率
  12.   DCOCTL=DCO2+DCO1+DCO0;//DCO为最高频率
  13.   do{
  14.     IFG1&=~OFIFG;//清除振荡器失效标志
  15.     for(unsigned int i=255;i>0;i--);
  16.   }while(IFG1&OFIFG);//判断XT2是否起振
  17.   BCSCTL2=SELM1+SELS;//MCLK SMCLK时钟源为TX2CLK不分频
  18. }
  19. //延时函数
  20. void delay(unsigned int m){
  21. for(unsigned int i=0;i
  22. _NOP();
  23. }
  24. void Lcd_InsWrite(uchar type,uchar transdata) //串行通信传输函数 ,transdata为要写入的数据或指令
  25. {
  26. uchar firsttype=0xf8; //firsttype为第一字节,用来判断是写数据还是写指令。默认是写指令
  27. uchar temp;
  28. uchar i,j=3;
  29.        
  30. if(type) //判断是是写数据还是写指令,0为写指令,1为写数据
  31. firsttype=firsttype|0x02; //如果要写数据,则把第一字节的第二位至高
  32. P1OUT|=BIT0; //给CS高电平开始写入操作
  33. P1OUT&=~BIT2; //给SCLK时钟脉冲,在每个上升沿把数据写入到LCD
  34. while(j>0) //把写数据指令方式和要写入的数据发送给LCD
  35. {
  36. if(j==3) temp=firsttype; //确认要写入第一字节数据,及数据指令判断
  37. else if(j==2) temp=transdata&0xf0;//确认要写入第二字节数据
  38. else temp=(transdata<<4)&0xf0; //确认要写入第三字节数据
  39. for(i=8;i>0;i--) //把要写入的数据每个位由STD发送到LCD,写入
  40. {
  41. if(temp&0x80) P1OUT|=BIT1; //写入第一字节,及最高字节
  42. else P1OUT&=~BIT1;
  43. P1OUT|=BIT2; //给SCLK一个上升沿,写入一位
  44. temp<<=1; //把数据指令左移一位,开始写入下一位数据
  45. P1OUT&=~BIT2; //给SCLK一个低电平,确保下一次写入数据正常
  46. }
  47. delay(1); //做简单的延时
  48. j--; //准备写入下一字节数据
  49. }
  50. P1OUT&=~BIT0; //写入数据指令完毕,给STD和CS低电平
  51. P1OUT&=~BIT1;
  52. }


  53. //ADC12采样初始化,并打开中断子程序计算采样值的大小
  54. void initADC12(){

  55. P6SEL=0X01;//P6.0作为模拟输入
  56. ADC12IE=0X01; //开放中断ADC12IFG.0
  57. ADC12CTL0=ADC12ON+SHT0_4+REFON+REF2_5V;//打开ADC转换的核,采用内部参考电压2.5v;
  58. ADC12CTL1=SHP;   //信号源内部触发
  59. ADC12MCTL0=SREF_1;//使用内部2.5V作为参考电压
  60. ADC12CTL0 |=ENC;  //开放使能

  61.   for (;;)
  62.   {
  63.     ADC12CTL0 |= ADC12SC;                   // Sampling open
  64.     _BIS_SR( GIE);                 //关闭CPU打开总中断
  65.   }
  66. }


  67. #pragma vector=ADC_VECTOR
  68. __interrupt void ADC12ISR(){
  69. data=ADC12MEM0*2.5/4095;  //data为全局变量
  70. Lcd_InsWrite(0,0x02);//DDRAM地址归位
  71. }

  72. //LCD初始化函数
  73. //函数声明:采用MSP430端口p3.5-3.7连接LCD的E,RW,和RS端口;P4口用来传送数据
  74. void init_lcd(void)
  75. {
  76. Lcd_InsWrite(0,0x30); //基本指令
  77. delay(400);
  78. Lcd_InsWrite(0,0x01); //清除显示
  79. delay(400);
  80. Lcd_InsWrite(0,0x0e);
  81. // 显示状态设定:整体显示,游标on,游标位置反白
  82. Lcd_InsWrite(0,0x02);//DDRAM地址归位
  83. delay(400);
  84. }


  85. //将ADC转换后的值写入LCD
  86. void WriteData(){
  87. data*=100;
  88. int temp=(int)data;
  89. a=temp/100;//考虑到由于内部参考电压的限制,且仅考虑两位小数的情况
  90. b=(temp%100)/10;
  91. c=(temp%10);
  92. Lcd_InsWrite(1,a+0x30);
  93. Lcd_InsWrite(1,'.');
  94. Lcd_InsWrite(1,b+0x30);
  95. Lcd_InsWrite(1,c+0x30);
  96. delay(400);
  97. }

  98. //主函数部分
  99. void main(){       
  100.   double temp=0.0;
  101. WDTCTL=WDTPW+WDTHOLD;//关闭看门狗
  102. initClock();//初始化时钟
  103. initADC12();//ADC12采样初始化,并打开中断子程序计算采样值的大小
  104. init_lcd(); //lcd初始化
  105. while(1){
  106.   if(data!=temp){
  107. temp=data;   
  108. Lcd_InsWrite(0,0x80);//确定显示位置
  109. WriteData(); //将采样值分别计算出对应位的输出
  110. }
  111. }
  112. }











复制代码 此帖出自小平头技术问答
友情提示: 此问题已得到解决,问题已经关闭,关闭后问题禁止继续编辑,回答。
6条回答
shenlei190810
2019-03-25 09:41
恩恩,谢谢你,你说的很有道理,我再看了下书,上面写的是0x01是光标回原位;0x02的意思是光标回原点;一字之差啊。

一周热门 更多>

相关问题

    相关文章