找回密码
 立即注册

QQ登录

只需一步,快速开始

搜索
查看: 1847|回复: 2
打印 上一主题 下一主题
收起左侧

iar for avr 编程 通过 仿真数码管显示不全 请求指导

[复制链接]
跳转到指定楼层
楼主
   学习《AVR单片机与传感器模块设计》(IAR) 教材,ATMega16 的A/D转换编程实践
                       编程通过   但是仿真 显示不全




  1. #include <iom16.h>
  2. unsigned char const SEG7[10] = {0xc0,0xf9,0xa4,0xb0,0x99,0x92,0x82,0xf8,0x80,0x90}; //用数组来预存数码管显示字符0~9的花样数据
  3. unsigned char const ACT[4] = {0x01,0x02,0x04,0x08}; //定义动态扫描位的变量以及接收到数据标志 0xfe,0xfd,0xfb,0xf7
  4. unsigned int dis_val;    //定义显示变量
  5. unsigned char i;        //定义动态扫描位的变量
  6. //===========================端口初始化=======================================
  7. void port_init(void)
  8. {
  9. PORTA = 0x00;
  10. DDRA = 0x00;       //PORTA初始化为悬浮输入
  11. PORTB = 0xff;
  12. DDRB = 0xff;
  13. PORTC = 0xff;
  14. DDRC = 0xff;
  15. }
  16. //===========================ADC初始化========================================
  17. void adc_init(void)
  18. {
  19. ADCSRA = 0xEE;   //使能ADC、开始转换、自动触发、使能中断、8预分频
  20. ADMUX = 0x40;      //使用AVCC做基准电压源、数据格式为右对齐、选择通道0
  21. }
  22. //============================定时器0初始化===================================
  23. void timer0_init(void)
  24. {
  25. TCNT0 = 0x83;      //定时1ms的初始值
  26. TCCR0 = 0x03;      //64预分频
  27. TIMSK = 0x01;       //使能定时器0溢出中断
  28. }
  29. //=============================设备初始化=====================================
  30. void init_devices(void)
  31. {
  32. port_init();       //调用端口初始化
  33. timer0_init();     //调用定时器0初始化
  34. adc_init();        //调用ADC初始化
  35. SREG = 0x80;       //打开全局中断
  36. }
  37. //===============================A/D转换======================================
  38. unsigned int ADC_Convert(void)
  39. {
  40. unsigned int temp1,temp2;
  41. temp1 = (unsigned int)ADCL;         //先读取低8位数据
  42. temp2 = (unsigned int)ADCH;         //再读取高8位数据
  43. temp2 = (temp2<<8)+temp1;          //高8位左移两位与低8位合并成10位数据
  44. return(temp2);                                //返回合并后的值
  45. }
  46. //==============================数据转换======================================
  47. unsigned int conv(unsigned int i)
  48. {
  49. long x;
  50. unsigned int y;
  51. x = (4840*(long)i)/1023;      //把变量转化成需要显示的形式
  52. y = (unsigned int)x;             //把无符号长整型变量强制转换成无符号整型变量
  53. return y;                              //返回转换后的值
  54. }
  55. //==============================主函数========================================
  56. void main(void)
  57. {
  58. init_devices();  //调用设备初始化
  59. while(1)
  60. {
  61.     ;             //空循环
  62. }
  63. }
  64. //=======================中断函数(定时器0溢出中断)============================
  65. #pragma vector = TIMER0_OVF_vect
  66. __interrupt void TIMER0_OVF_Server(void)
  67. {
  68. TCNT0 = 0x83;    //重载初值
  69. if(++i>3)        //扫描位数为4位
  70.   i = 0;
  71. switch(i)
  72. {
  73.   case 0:PORTB = SEG7[dis_val%10];          //送个位待显示的数据
  74.         PORTC = ACT[0];                //打开个位显示(点亮)
  75.    break;
  76.   case 1:PORTB = SEG7[(dis_val/10)%10];     //送十位待显示的数据
  77.         PORTC = ACT[1];                //打开十位显示(点亮)
  78.    break;
  79.   case 2:PORTB = SEG7[(dis_val/100)%10];    //送百位待显示的数据
  80.         PORTC = ACT[2];                //打开百位显示(点亮)
  81.    break;
  82.   case 3:PORTB = SEG7[dis_val/1000]&0x7F;   //送千位待显示的数据并点亮小数点
  83.         PORTC = ACT[3];                //打开千位显示(点亮)
  84.    break;
  85. }
  86. }
  87. //=======================中断函数(A/D转换结束中断)============================
  88. #pragma vector = ADC_vect
  89. __interrupt void ADC_Server(void)
  90. {
  91.   dis_val = conv(ADC_Convert());        //获取A/D转换数据并送显
  92. }

复制代码



分享到:  QQ好友和群QQ好友和群 QQ空间QQ空间 腾讯微博腾讯微博 腾讯朋友腾讯朋友
收藏收藏 分享淘帖 顶 踩
回复

使用道具 举报

沙发
ID:213173 发表于 2021-3-1 21:32 | 只看该作者
从图片现象看是显示函数没有消隐导致乱码,实际电路不会出现乱码但会有鬼影。添加消隐代码。
  1. //=======================中断函数(定时器0溢出中断)============================
  2. #pragma vector = TIMER0_OVF_vect
  3. __interrupt void TIMER0_OVF_Server(void)
  4. {
  5.         TCNT0 = 0x83;    //重载初值
  6.         if(++i>3)        //扫描位数为4位
  7.         i = 0;
  8.         PORTC = 0x00;//消隐
  9.         switch(i)
  10.         {
  11.                 case 0:PORTB = SEG7[dis_val%10];          //送个位待显示的数据
  12.                 PORTC = ACT[0];                //打开个位显示(点亮)
  13.                 break;
  14.                 case 1:PORTB = SEG7[(dis_val/10)%10];     //送十位待显示的数据
  15.                 PORTC = ACT[1];                //打开十位显示(点亮)
  16.                 break;
  17.                 case 2:PORTB = SEG7[(dis_val/100)%10];    //送百位待显示的数据
  18.                 PORTC = ACT[2];                //打开百位显示(点亮)
  19.                 break;
  20.                 case 3:PORTB = SEG7[dis_val/1000]&0x7F;   //送千位待显示的数据并点亮小数点
  21.                 PORTC = ACT[3];                //打开千位显示(点亮)
  22.                 break;
  23.         }
  24. }
复制代码
回复

使用道具 举报

板凳
ID:44037 发表于 2021-3-2 13:01 | 只看该作者
谢谢指导!  正常显示了  
      请问 显示有误差,怎样提高精度   x = (4840*(long)i)/1023;   4840 有的程序不是这个值!
      非常感谢!!!
回复

使用道具 举报

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

本版积分规则

手机版|小黑屋|51黑电子论坛 |51黑电子论坛6群 QQ 管理员QQ:125739409;技术交流QQ群281945664

Powered by 单片机教程网

快速回复 返回顶部 返回列表