3262|6

15

帖子

0

TA的资源

一粒金砂(中级)

楼主
 

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

  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. }











复制代码

最新回复

Lcd_InsWrite(0,0x01)应该是清屏,但光标不复位吧,就是说写这个指令前,光标在哪,写完这个指令后,光标还在那,再次写入数据,光标一直往后移,多写几次后,光标就溢出了,就不知道跑到哪去了,因为你的while循环里没有光标复位的语句了,这只是我个人理解,我没用过12864 而且这句话有问题:if(data!=temp){temp=data;浮点型数据不能比较相等,只能比较大小 [ 本帖最后由 wudayongnb 于 2013-6-2 17:00 编辑 ]  详情 回复 发表于 2013-6-2 16:51

点评

一直在初始化ADC的函数里循环了,LCD肯定没显示  详情 回复 发表于 2013-6-1 16:17
 
点赞 关注

回复
举报

373

帖子

0

TA的资源

纯净的硅(中级)

沙发
 

回复 楼主 shenlei190810 的帖子

一直在初始化ADC的函数里循环了,LCD肯定没显示

点评

原帖由 wudayongnb 于 2013-6-1 16:17 发表 https://bbs.eeworld.com.cn/images/common/back.gif 一直在初始化ADC的函数里循环了,LCD肯定没显示 对,是这样的,我修改了下:这样你看看怎么还是没显示:#include  详情 回复 发表于 2013-6-1 18:19
 
 

回复

15

帖子

0

TA的资源

一粒金砂(中级)

板凳
 
原帖由 wudayongnb 于 2013-6-1 16:17 发表
一直在初始化ADC的函数里循环了,LCD肯定没显示

对,是这样的,我修改了下:这样你看看怎么还是没显示:
  1. #include  
  2. #define uchar unsigned char
  3. #define uint unsigned int
  4.   double data;//用来存储ADC12MEM中的数据
  5.   char a,b,c=0; //用来存储将要显示在LCD上的各位数据

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


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

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

  59. #pragma vector=ADC_VECTOR
  60. __interrupt void ADC12ISR(){
  61. data=ADC12MEM0*2.5/4095;  //data为全局变量
  62. Lcd_InsWrite(0,0x02);
  63. _BIC_SR_IRQ(CPUOFF);                    // Clear CPUOFF bit from 0(SR)
  64. }

  65. //LCD初始化函数
  66. //函数声明:采用MSP430端口p3.5-3.7连接LCD的E,RW,和RS端口;P4口用来传送数据
  67. void init_lcd(void)
  68. {
  69. Lcd_InsWrite(0,0x30); //基本指令
  70. delay(400);
  71. Lcd_InsWrite(0,0x04); //清除显示
  72. delay(400);
  73. Lcd_InsWrite(0,0x0c); //
  74. delay(400);

  75. Lcd_InsWrite(0,0x01);
  76. delay(400);// 显示状态设定:整体显示,游标on,游标位置反白
  77. Lcd_InsWrite(0,0x02);//DDRAM地址归位
  78. delay(400);
  79. }


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

  96. //主函数部分
  97. void main(){       
  98.   double temp=0.0;
  99. WDTCTL=WDTPW+WDTHOLD;//关闭看门狗
  100. initClock();//初始化时钟
  101. init_lcd(); //lcd初始化
  102. initADC12();//ADC12采样初始化,并打开中断子程序计算采样值的大小

  103. while(1){
  104.   if(data!=temp){
  105. temp=data;   
  106. WriteData(); //将采样值分别计算出对应位的输出
  107.   }
  108.     ADC12CTL0 |= ADC12SC;                   // Sampling open
  109.     _BIS_SR( GIE);                 //关闭CPU打开总中断
  110. }

  111. }
复制代码

点评

你先确定你的LCD部分是不是调通了,再加上AD部分  详情 回复 发表于 2013-6-1 19:49
 
 
 

回复

373

帖子

0

TA的资源

纯净的硅(中级)

4
 

回复 板凳 shenlei190810 的帖子

你先确定你的LCD部分是不是调通了,再加上AD部分

点评

恩恩,现在这个问题已经解决了,谢谢你了;现在还有一个问题想请教您。这段代码的意思是,采样值和之前的不一样,也就是重新测得一个电压的时候就重新写入一个新的值; 现在的问题是Lcd_InsWrite(0,0x02); 这个表示  详情 回复 发表于 2013-6-2 12:58
 
 
 

回复

15

帖子

0

TA的资源

一粒金砂(中级)

5
 
原帖由 wudayongnb 于 2013-6-1 19:49 发表
你先确定你的LCD部分是不是调通了,再加上AD部分
恩恩,现在这个问题已经解决了,谢谢你了;现在还有一个问题想请教您。这段代码的意思是,采样值和之前的不一样,也就是重新测得一个电压的时候就重新写入一个新的值;
现在的问题是Lcd_InsWrite(0,0x02); 这个表示光标回到原点,不擦除DDRAM的值,我把这个修改成Lcd_InsWrite(0,0x01);就是擦除DDRAM的值,我觉得在这个位置使用这两种都可以啊,因为都是要空头开始重新开始写入的;但是在实际操作中后者不行,请问什么原因?
  1. while(1)
  2.   {
  3.      ADC12CTL0 |= ADC12SC;                   // Sampling open
  4.     _BIS_SR(CPUOFF + GIE);                  // LPM0, ADC12_ISR will force exit
  5.         if(temp!=data)
  6.     {
  7. temp=data;
  8. Lcd_InsWrite(0,0x02);
  9.      WriteData();
  10.     }

  11. }
复制代码

点评

Lcd_InsWrite(0,0x01)应该是清屏,但光标不复位吧,就是说写这个指令前,光标在哪,写完这个指令后,光标还在那,再次写入数据,光标一直往后移,多写几次后,光标就溢出了,就不知道跑到哪去了,因为你的while循环  详情 回复 发表于 2013-6-2 16:51
 
 
 

回复

373

帖子

0

TA的资源

纯净的硅(中级)

6
 

回复 5楼 shenlei190810 的帖子

Lcd_InsWrite(0,0x01)应该是清屏,但光标不复位吧,就是说写这个指令前,光标在哪,写完这个指令后,光标还在那,再次写入数据,光标一直往后移,多写几次后,光标就溢出了,就不知道跑到哪去了,因为你的while循环里没有光标复位的语句了,这只是我个人理解,我没用过12864
而且这句话有问题:
  • if(data!=temp){
  • temp=data;
  • 浮点型数据不能比较相等,只能比较大小


[ 本帖最后由 wudayongnb 于 2013-6-2 17:00 编辑 ]

点评

恩恩,谢谢你,你说的很有道理,我再看了下书,上面写的是0x01是光标回原位;0x02的意思是光标回原点;一字之差啊。  详情 回复 发表于 2013-6-2 18:48
 
 
 

回复

15

帖子

0

TA的资源

一粒金砂(中级)

7
 

回复 6楼 wudayongnb 的帖子

恩恩,谢谢你,你说的很有道理,我再看了下书,上面写的是0x01是光标回原位;0x02的意思是光标回原点;一字之差啊。
 
 
 

回复
您需要登录后才可以回帖 登录 | 注册

随便看看
查找数据手册?

EEWorld Datasheet 技术支持

相关文章 更多>>
关闭
站长推荐上一条 1/10 下一条

 
EEWorld订阅号

 
EEWorld服务号

 
汽车开发圈

About Us 关于我们 客户服务 联系方式 器件索引 网站地图 最新更新 手机版

站点相关: 国产芯 安防电子 汽车电子 手机便携 工业控制 家用电子 医疗电子 测试测量 网络通信 物联网

北京市海淀区中关村大街18号B座15层1530室 电话:(010)82350740 邮编:100190

电子工程世界版权所有 京B2-20211791 京ICP备10001474号-1 电信业务审批[2006]字第258号函 京公网安备 11010802033920号 Copyright © 2005-2024 EEWORLD.com.cn, Inc. All rights reserved
快速回复 返回顶部 返回列表