查看: 3425|回复: 4

MEGA1284P试用记录及心得 学习笔记(五) 上位机控制数码管显...

[复制链接]
  • TA的每日心情
    开心
    2022-4-12 14:51
  • 签到天数: 163 天

    连续签到: 1 天

    [LV.7]常住居民III

    发表于 2013-12-1 23:33:44 | 显示全部楼层 |阅读模式
    分享到:
    本帖最后由 wspytu 于 2013-12-2 18:18 编辑

    试用MEGA1284P开发板终极目标是:MCU驱动8位8段数码管,显示时间、日期、温度等信息,通过上位机或15键无线遥控控制数码管显示模式,或修改当前时间或日期。
    具体方案如下:MCU使用3个GPIO引脚以串转并方式通过74HC244驱动8位数码管;通过16位TIMER1计数CTC模式计时;上位机软件通过串口控件向MCU发送控制信息,对应无线遥控,上位机界面也包含15个按键;15键无线遥控包含0-9按键值、功能键、左移、右移、确认、取消键,MCU模拟PT2262解码,通过采集无线接受模块数据引脚信息,判断按键值,功能键控制数码管显示模式,0-9按键值调整当前时间或日期,其他键为辅助功能。
    MEGA1284P试用板、数码管显示板、无线遥控模块整体如下图所示:

    ScreenHunter_006.jpg

    15键无线遥控发送和接收模块:

    ScreenHunter_001.jpg

    本篇帖子只实现了MCU控制部分,无线解码还没有调试,上位机软件只实现了部分界面,不过通过串口调试助手发送相应指令,控制数码管显示功能已实现(注:串口通讯没有添加校验)。通讯协议如下:
    时间数组,上位机调整时间或日期时发送,MCU每隔5s主动发送
    00 0A 13 11 1E 08 1E 00 00 58
    0) 00 功能码
    1) 0A 总字节长度
    2-4) 13 11 1E 年月日
    5-7) 08 1E 00 时分秒
    8) 00 100ms值,从0-10
    9) 58 结束符,Xplan X=0X58

    按键控制,上位机发送,MCU接收后再返回
    00 04 00 58
    0) 00 功能码
    1) 04 总字节长度
    2) 00 按键值,范围00-0E,00-09代表0-9数值,0A表示功能键,0B左移,0C右移,0D确认,0E取消
    3) 58 结束符

    温度,数码管显示模式为温度时,MCU主动发送给上位机
    00 06 01 02 0058
    0) 00 功能码
    1) 06 总字节长度
    2-4) 01 02 00 温度值,分别为温度十位、个位、小数位
    5) 58 结束符

    数码管显示图片如下,默认上电时间为08:30:00,日期13-11-30
    ScreenHunter_002.jpg

    部分代码如下:
    注意事项、变量和数组定义如下:
    //13年11月30日

    //NTC温度ADC908对应2.27v 25(基准电压2.56),最高温度约28.2

    //USART1接受按键数值,每隔200ms判断一次按键

    //USART1接受使用中断模式,发送不占用中断,TXCIE1=0

    //定义数组长度时,一定要实际长度+1个结束符(数码管显示,数组长度原定义10个字节,数码管显示'9'不正常)

    /*
    数码管驱动,0点亮,1灭,带小数点,位控制序列如下
            -7-
           |2     |6
            -1-
           |3     |5
            -4- .0
    */

    //LED顺时针方向ED0-PB0 LED2-PB1 LED3-PB2 LED1-PB3
    //LED接上拉电阻,低电平点亮;引脚配置为输出时,向PINX对应引脚写入1,会自动翻转TOGGLING引脚电平

    #include "avr_compiler.h"

    #define ADC_NUM_OVERSAMPLING            16

    enum adc_sources
    {
           FILTER_OUTPUT= 0x05,                                                    //!<RC filter on ADC Channel 5, PA5
           LIGHT_SENSOR= 0x06,                                                    //!<Light Sensor on ADC Channel 6, PA6
           NTC= 0x07                                                                 //!< NTCsensor on ADC Channel 7, PA7
    };


    static volatile bool Time1s_flag=0;
    static volatile bool Send_flag=0;
    static volatile bool KeySet_flag=0;

    static volatile bool Disflash_flag=0;                                   //按下设置标志位,按下确认清零
    static volatile bool DisEn_flag=0;                                      //数码管显示允许标志位,数码管正常显示1分钟后关闭

    static volatile bool Temp_Rdflag=0;                                         //读当前温度标志位

    static volatile unsigned charTime10ms_cnt=0;                  //定时10ms计数变量
    static volatile unsigned char Rx1_cnt=0;                           //串口接受字节计数变量
    static volatile unsigned char Send_len=0;                           //串口接受字节计数变量
    static volatile unsigned charKeySet_value=0;                    //串口发送按键值

    unsigned char Setup_Value=0;                                                 //功能设置计数变量
    unsigned char DI_Flash=0;  
    unsigned char Disflash_cnt=0;  
    unsigned char DisEn_cnt=0;
    unsigned char DI_A=0;
    unsigned char DI_B=0;
    unsigned char DI_C=0;
    unsigned char Keyin_cnt=0;                                                   //6位数码管输入按键值计数变量
    unsigned int Temp_value=0;                                                   //当前温度*10,避免小数位

    //数码管显示数组0-9
    const unsigned charClock_Display[16]={0x03,0x9f,0x25,0x0d,0x99,0x49,0x41,0x1f,0x01,0x09};      

    static volatile unsigned charTimeBuf[8]={13,11,30,8,30,0};

    static volatile unsigned charRx1_buf[32]={0};                 //串口接收数组
    static volatile unsigned charTx1_buf[32]={0};                 //串口发送数组

    unsigned char Keyin_buf[7]={0};                                           //6位数码管按键调整值

    MCU GPIOTIMER1USART1ADC初始化,可参考官方例程,只是串口使用接收中断方式;温度读取程序参考官方例程;数码管显示和按键处理部分程序代码较多,感兴趣的可以查看附件。

    串口发送程序如下:
    void usart1_send(volatile unsigned charbuf[],volatile unsigned char len)
    {
           unsignedchar i;

           for(i=0;i<len;i++)
           {
                  UCSR1A |= (1 << TXC1);
                  while(!(UCSR1A & (1 <<UDRE1)));                       // Waitfor empty transmit buffer
                  UDR1= buf;
           }
    }
    主函数处理程序如下:
    int main(void)
    {
           volatileunsigned char i;

           mega1284p_init();

           DisEn_flag= 1;
           DisEn_cnt= 0;

           while(1)
           {
                  if(Time1s_flag)
                  {
                         Time1s_flag= 0;

                         Time_Process();

                         if((TimeBuf[5]% 2) == 0)
                                PORTB|= 0x01;
                         else
                                PORTB&= 0xfe;

                         Time_Display();            

                         if((TimeBuf[5]% 5) == 0)
                         {
                                for(i=0;i<6;i++)
                                {
                                       Tx1_buf[i+2]= TimeBuf;
                                }
                                Tx1_buf[8]= Time10ms_cnt;      
                                Send_flag= 1;
                                Send_len= 10;      
                         }
                         if(DisEn_flag)
                         {
                                DisEn_cnt++;
                                if(DisEn_cnt> 60)
                                {
                                       DisEn_cnt= 0;
                                       DisEn_flag= 0;
                                       Disflash_flag= 0;
                                       Setup_Value= 0;
                                       DI_Flash= 0;
                                }
                                if(Disflash_flag)
                                {
                                       Disflash_cnt++;
                                       if(Disflash_cnt> 20)            //超过20s没有按确认键自动取消
                                       {
                                              Disflash_cnt= 0;
                                              Disflash_flag= 0;
                                              Setup_Value= 0;
                                              DI_Flash= 0;
                                       }
                                }
                         }
                  }     
                  if(Send_flag)
                  {
                         Send_flag= 0;
                         Tx1_buf[0]= 0;
                         Tx1_buf[1]= Send_len;
                         Tx1_buf[Send_len-1]= 0x58;              //结束符
                         usart1_send(Tx1_buf,Send_len);
                  }
                  if(KeySet_flag)
                  {
                         KeySet_flag= 0;
                         Key_Scan();
                  }
                  if(Temp_Rdflag)
                  {
                         Temp_Rdflag= 0;  
                         read_ntc();
                         Tx1_buf[2]= Temp_value / 100;
                         Tx1_buf[3]= (Temp_value % 100) / 10;
                         Tx1_buf[4]= Temp_value % 10;
                         Send_flag= 1;
                         Send_len= 6;
                  }
           }
    }
    TIEMR1中断程序如下;
    ISR(TIMER1_COMPA_vect)                                          //TIMER1CTC中断
    {
           Time10ms_cnt++;
           if(Time10ms_cnt>= 100)
           {
                  Time10ms_cnt= 0;
                  Time1s_flag= 1;
           }
    }
    串口接收中断程序如下,MCU接收到时间数组、按键数组后,向上位机返回接收到的数组:
    ISR(USART1_RX_vect)                                                 //USART1 RX中断
    {
           unsignedchar i;
           unsignedchar Rx_ch=0;
           Rx_ch= UDR1;
           if(Rx1_cnt== 0)
           {
                  if(Rx_ch== 0)
                  {
                         Rx1_buf[Rx1_cnt]= Rx_ch;
                         Rx1_cnt++;
                  }
           }
           else
           {
                  Rx1_buf[Rx1_cnt]= Rx_ch;
                  Rx1_cnt++;
                  if(Rx1_cnt> 30)
                         Rx1_cnt= 0;
                  if(Rx1_cnt== Rx1_buf[1])                 
                  {
                         Rx1_cnt= 0;
                         if((Rx1_buf[1]== 0x0A) &&(Rx1_buf[9] == 0x58))
                         {
                                for(i=0;i<6;i++)
                                {
                                       TimeBuf= Rx1_buf[i+2];

                                       Tx1_buf[i+2]= Rx1_buf[i+2];            
                                }
                                Time10ms_cnt= Rx1_buf[8];

                                Send_flag= 1;
                                Send_len= 10;
                         }
                         elseif((Rx1_buf[1] == 0x04) && (Rx1_buf[3] == 0x58))
                         {
                                if(Rx1_buf[1]< 16)                     //15个按键
                                {
                                       KeySet_flag= 1;
                                       KeySet_value= Rx1_buf[2];  
                                       Tx1_buf[2]= Rx1_buf[2];

                                       Send_flag= 1;
                                       Send_len= 4;
                                }
                         }
                  }
           }
    }


    file:///C:/DOCUME~1/ADMINI~1/LOCALS~1/Temp/msohtml1/01/clip_image004.jpg

    移位数码管闪烁如下:

    ScreenHunter_003.jpg
    file:///C:/DOCUME~1/ADMINI~1/LOCALS~1/Temp/msohtml1/01/clip_image006.jpg

    日期数码管闪烁如下:

    ScreenHunter_004.jpg
    file:///C:/DOCUME~1/ADMINI~1/LOCALS~1/Temp/msohtml1/01/clip_image008.jpg



    通过串口调试,更改为当前时间,15:24:00,数码管显示如下:
    file:///C:/DOCUME~1/ADMINI~1/LOCALS~1/Temp/msohtml1/01/clip_image010.jpg
    ScreenHunter_005.jpg

    温度显示,长沙121日下午温度为10(温度读取有误差,有一次看到时12.2)中间小点不亮,可能是硬件没有控制小点位,数码管显示如下:

    因为用同事手机拍摄,这张照片没有拷过来,大家就见谅吧

    VB编写的上位机部分界面如下(在长沙到深圳高铁路上截的图片):
    ScreenHunter_2.jpg

    1次自己写VB程序,进程有点慢,还没进行调试。

    整个工程如下,所有处理都写在main.c文件,没有分类,请大家不要介意;程序编写不严谨,仅供参考:
    led_timer_131130.rar (46.16 KB, 下载次数: 7)
    回复

    使用道具 举报

  • TA的每日心情
    奋斗
    2014-7-16 09:10
  • 签到天数: 361 天

    连续签到: 1 天

    [LV.8]以坛为家I

    发表于 2013-12-2 09:19:19 | 显示全部楼层
    给个大大的赞诺!就系Fighting!!!
    回复 支持 反对

    使用道具 举报

  • TA的每日心情
    开心
    2022-4-12 14:51
  • 签到天数: 163 天

    连续签到: 1 天

    [LV.7]常住居民III

     楼主| 发表于 2013-12-2 18:20:42 | 显示全部楼层
    GY@艳 发表于 2013-12-2 09:19
    给个大大的赞诺!就系Fighting!!!

    艳子,好谢谢你哦!
    谢谢你的赞许!
    I am fighting!
    回复 支持 反对

    使用道具 举报

  • TA的每日心情

    2013-12-16 10:30
  • 签到天数: 23 天

    连续签到: 1 天

    [LV.4]偶尔看看III

    发表于 2013-12-10 10:55:14 | 显示全部楼层
    强大的帖子,支持到底!
    回复 支持 反对

    使用道具 举报

  • TA的每日心情
    奋斗
    2015-1-22 18:04
  • 签到天数: 189 天

    连续签到: 1 天

    [LV.7]常住居民III

    发表于 2013-12-29 17:42:14 | 显示全部楼层
    不错不错~~VB还是很好用的
    回复 支持 反对

    使用道具 举报

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

    本版积分规则

    关闭

    站长推荐上一条 /4 下一条

    手机版|小黑屋|与非网

    GMT+8, 2024-11-20 01:51 , Processed in 0.153644 second(s), 24 queries , MemCache On.

    ICP经营许可证 苏B2-20140176  苏ICP备14012660号-2   苏州灵动帧格网络科技有限公司 版权所有.

    苏公网安备 32059002001037号

    Powered by Discuz! X3.4

    Copyright © 2001-2024, Tencent Cloud.