提示:文章写完后,目录可以自动生成,如何生成可参考右边的帮助文档

CMS80F251xEVB使用

文章目录

  • 前言
  • 一、LCD默认进入时钟模式,P50按键按下一次进入闹钟模式,再按一次退出闹钟模式
  • 二、P20按两次,选中分钟,再按一次,分钟加一,再按两次,选中秒钟,按一次,秒钟加一
  • 三、时钟等于闹钟,D2灯亮灭三次,这时P20按一次,闹钟清零
  • 四、P50按两次,进入串口模式
  • 总结

前言

EVB板c51程序


一、LCD默认进入时钟模式,P50按键按下一次进入闹钟模式,再按一次退出闹钟模式

二、P20按两次,选中分钟,再按一次,分钟加一,再按两次,选中秒钟,按一次,秒钟加一

三、时钟等于闹钟,D2灯亮灭三次,这时P20按一次,闹钟清零

四、P50按两次,进入串口模式

代码如下:

#include "dis_timer.h"
#define KEY1_STATE_0 0
#define KEY1_STATE_1 1
#define KEY1_STATE_2 2
#define KEY1_STATE_3 3#define KEY2_STATE_0 0
#define KEY2_STATE_1 1
#define KEY2_STATE_2 2
#define KEY2_STATE_3 3#define SINGLE_KEY1_TIME 1  //10ms
#define KEY1_INTERVAL 30 //300ms#define SINGLE_KEY2_TIME 1
#define KEY2_INTERVAL 30#define KEY1_NONE   0 //
#define KEY1_SHORT  1 //单击
#define KEY1_DOUBLE 2 //双击#define KEY2_NONE      0
#define KEY2_SHORT   1
#define KEY2_DOUBLE  2
unsigned char leddata[16][2]={{0x07,0x0d},{0x00,0x05},{0x05,0x0b},{0x01,0x0f},{0x02,0x07},{0x03,0x0e},{0x07,0x0e},{0x01,0x05},{0x07,0x0f},{0x03,0x0f},{0x07,0x07},{0x06,0x0e},{0x07,0x08},{0x04,0x0f},{0x07,0x0a},{0x07,0x02}};
unsigned char leddata1[10][2]={{0x0f,0x0d},{0x08,0x05},{0x0d,0x0b},{0x09,0x0f},{0x0a,0x07},{0x0b,0x0e},{0x0a,0x0e},{0x09,0x05},{0x0a,0x0f},{0x0b,0x0f}};
unsigned char dat[4]={0x89,0xAB,0xCD,0xEF};
int flag=0,flag1=0,flag2=0,flag3=0,flag4=0,flag5=0,flag6=0,min_sec;
unsigned char P20_KeyValue,P20_KeyValue1,P50_KeyValue;
unsigned char P20_flag_10ms_key,P20_flag_10ms_key1,P50_flag_10ms_key;
unsigned int s1,s2,s3,s4,ss3=0,ss4=0,ss1=0,ss2=0;
unsigned int we,i,time=0,time1,time2,t1,t2,t3,temp,temp1,temp2;//***************************************************//
//************Config************//
//***************************************************//
void UART0_Config(void)
{ BRTCON=0X80; //BRT使能;BRTDL=0x64;//计数器初值,65380,波特率9600;BRTDH=0xff; FUNCCR=0x05; //UART0,BRT溢出时钟SCON0=0X70; //多机控制,接受使能,8位异步模式PCON=0X80;//波特率加倍PS_RXD0=0X25;//P25作为引脚RXP25CFG=0X02;//P25 RX功能P24CFG=0X02;//P24 TXD0功能ES0=1;//允许中断
//  uint16_t  BRTValue = 0;
//   uint32_t  BaudRateVlue = 9600;
//
//
//  // (1)设置UARTx的运行模式
//
//   UART_ConfigRunMode(UART0,UART_MOD_ASY_8BIT, UART_BAUD_BRT);
//   UART_EnableReceive(UART0);
//
//   //(2)配置UARTx的波特率
//
//   UART_ConfigBRTClk(BRT_CLK_DIV_1);
//
//   UART_EnableDoubleFrequency(UART0);                             /*波特率使能倍频:SMOD =1*/
//
//  #ifdef USE_FORMULA          //使用公式计算定时器的加载值(需要对Systemclock赋值(main.c)),USE_FORMULA 在 选项Option->C51->Preporcessor Symbols->Define中定义
//   BRTValue = UART_ConfigBaudRate(UART0, BaudRateVlue) ;
//  #else
//   BRTValue = 65380;                 //使用数据手册上推荐的加载值(BRT章节)
//  #endif
//
//   UART_ConfigBRTPeriod(BRTValue);                            /*配置重装值*/
//   UART_EnableBRT();                                      /*使能定时器*/
//
//   //(3)配置IO口//    GPIO_SET_MUX_MODE(P24CFG,GPIO_P24_MUX_TXD0);           /*TXD0*/
//   GPIO_SET_MUX_MODE(P25CFG,GPIO_P25_MUX_RXD0);           /*RXD0*/
//   GPIO_SET_PS_MODE(PS_RXD0, GPIO_P25);                   /*RXD0输入选择P25*/
//
//  // (4)设置UART中断
//
//  // UART_EnableInt(UART0);
//  // IRQ_SET_PRIORITY(IRQ_UART0,IRQ_PRIORITY_LOW);
}void GPIO_Config(void)
{GPIO_SET_MUX_MODE(P50CFG, GPIO_MUX_GPIO);          GPIO_ENABLE_INPUT(P5TRIS, GPIO_PIN_0);              GPIO_SET_MUX_MODE(P20CFG, GPIO_MUX_GPIO);           GPIO_ENABLE_INPUT(P2TRIS, GPIO_PIN_0);              GPIO_ENABLE_UP(P2UP, GPIO_PIN_0);GPIO_SET_MUX_MODE(P21CFG, GPIO_MUX_GPIO);          GPIO_ENABLE_OUTPUT(P2TRIS,GPIO_PIN_1);              GPIO_ENABLE_UP(P2UP, GPIO_PIN_1);             GPIO_SET_MUX_MODE(P22CFG, GPIO_MUX_GPIO);         GPIO_ENABLE_OUTPUT(P2TRIS,GPIO_PIN_2);              GPIO_ENABLE_UP(P2UP, GPIO_PIN_2);
}void TMR0_Config(void)//开定时器0中断
{/*(1)设置Timer的运行模式*/TMR_ConfigRunMode(TMR0, TMR_MODE_TIMING,TMR_TIM_16BIT); /*(2)设置Timer 运行时钟*/TMR_ConfigTimerClk(TMR0, TMR_CLK_DIV_12);                        /*Fsys = 24Mhz,Ftimer = 2Mhz,Ttmr=0.5us*//*(3)设置Timer周期*/ TMR_ConfigTimerPeriod(TMR0, 45536/256, 45536%256);              // 20000*0.5us = 10ms,递增计数/*(4)开启中断*/TMR_EnableOverflowInt(TMR0);/*(5)设置Timer中断优先级*/   IRQ_SET_PRIORITY(IRQ_TMR0,IRQ_PRIORITY_LOW);IRQ_ALL_ENABLE();   /*(6)开启Timer*/TMR_Start(TMR0);
}void LCD_Config(void)//设置lcd
{/*(1)设置LED模块运行模式*/LCD_ConfigRunMode(LCD_DISPLAY_NORMAL);LCD_ConfigCOMMode( LCD_DUTY_4);        //1/4DUTYLCD_ConfigVLCD(LCD_VSEL_VLCD, 15, LCD_BIAS_3); //VDD =5V, VLcv = 3.3V , 1/3biasLCD_ConfigClk(LCD_CLK_FSYS, LCD_CLKDIV_4096);LCD_ConfigResistance(LCD_FCMODE_0, LCD_R_60K, LCD_FCCTL_8);/*(2)设置COM口*/GPIO_SET_MUX_MODE(P00CFG, GPIO_MUX_ANA); //COM0GPIO_SET_MUX_MODE(P01CFG, GPIO_MUX_ANA);  //COM1  GPIO_SET_MUX_MODE(P02CFG, GPIO_MUX_ANA);    //COM2GPIO_SET_MUX_MODE(P03CFG, GPIO_MUX_ANA);  //COM3  LCDCOMEN = 0x0f;       //使能COM0~COM3/*(3)设置SEG口*/  GPIO_SET_MUX_MODE(P04CFG, GPIO_MUX_ANA);    //SEG0  -> 段码屏 SEG0GPIO_SET_MUX_MODE(P05CFG, GPIO_MUX_ANA);  //SEG1  -> 段码屏 SEG1GPIO_SET_MUX_MODE(P06CFG, GPIO_MUX_ANA);  //SEG2  -> 段码屏 SEG2  GPIO_SET_MUX_MODE(P07CFG, GPIO_MUX_ANA);    //SEG3  -> 段码屏 SEG3GPIO_SET_MUX_MODE(P10CFG, GPIO_MUX_ANA);  //SEG4  -> 段码屏 SEG4  GPIO_SET_MUX_MODE(P11CFG, GPIO_MUX_ANA);    //SEG5  -> 段码屏 SEG5  GPIO_SET_MUX_MODE(P12CFG, GPIO_MUX_ANA);    //SEG6  -> 段码屏 SEG6  GPIO_SET_MUX_MODE(P13CFG, GPIO_MUX_ANA);    //SEG7  -> 段码屏 SEG7  LCDSEGEN0 = 0xFF;  //使能SEG8~SEG15  /*(6)设置SEG口数据*/LCDSEG0 = 0x00;LCDSEG1 = 0x00; LCDSEG2 = 0x00;    LCDSEG3 = 0x00;LCDSEG4 = 0x00;LCDSEG5 = 0x00;LCDSEG6 = 0x00;LCDSEG7 = 0x00;/*(7)开启LCD*/LCD_Start();
}//***************************************************//
//************timer0和串口中断函数************//
//***************************************************//
void Timer0_IRQHandler(void)  interrupt TMR0_VECTOR
{  TMR_ConfigTimerPeriod(TMR0, 45536/256, 45536%256);               // 20000*0.5us = 10ms,递增计数time++;//lcd显示1s递增time1++;if(time1==50){t1=1;     //0.5s标志位,闹钟警报灯亮灭时间time1=0; }  time2++;if(time2==300){t2=1;     //3s标志位,发送数据时间time2=0; } P20_flag_10ms_key=1; // 置位 10ms 定时标志P20_flag_10ms_key1=1; // 置位 10ms 定时标志P50_flag_10ms_key=1; // 置位 10ms 定时标志for(we=0;we<4;we++){if(we == 0){   LCDSEG6 = leddata[s1][0];LCDSEG7 = leddata[s1][1];}if(we == 1){  LCDSEG4 = leddata[s2][0];LCDSEG5 = leddata[s2][1];}if(we == 2){      LCDSEG2 = leddata[s3][0];   LCDSEG3 = leddata[s3][1];}if(we == 3){      LCDSEG0 = leddata1[s4][0];LCDSEG1 = leddata1[s4][1];         }     }   }void UART0_IRQHandler(void)  interrupt UART0_VECTOR //串口中断
{//if(UART_GetSendIntFlag(UART0))
//  {
//      UART_ClearSendIntFlag(UART0);
//  }
//  if(UART_GetReceiveIntFlag(UART0))
//  {//      UART_SendBuff(UART0,UART_GetBuff(UART0));
//      UART_ClearReceiveIntFlag(UART0);
//  }if(RI0==1){temp=SBUF0;  //P21=0;RI0=0;}
}//***************************************************//
//**********向FPGA发送数据***********//
//***************************************************//
void putschar ()//发送数据
{   if(temp==0x11){P22=0;t3=1;}if(t2&&t3){SBUF0 = dat[i];i++;t2=0;if(i==4){i=0;}while (!TI0);TI0=0;}}//***************************************************//
//**************LCD显示功能***************//
//***************************************************//
void LCD_Display()//时钟显示
{ if(time==100){s1++;if(s1==10){s1=0;s2++;if(s2==6){s2=0;s3++;if(s3==10){s3=0;s4++;if(s4==6)s4=0;  }}}   time=0; }}void CLOCKINIT()//闹钟初始化显示
{  LCDSEG6 = leddata[ss1][0];LCDSEG7 = leddata[ss1][1];   LCDSEG4 = leddata[ss2][0];LCDSEG5 = leddata[ss2][1];  LCDSEG2 = leddata[ss3][0];LCDSEG3 = leddata[ss3][1];     LCDSEG0 = leddata1[ss4][0];LCDSEG1 = leddata1[ss4][1];}    void UART()//串口显示收到的数据
{if(flag6){//   putschar(6);//getschar();temp1=temp>>4;temp2=temp&0x0f;LCDSEG0 = leddata[temp1][0];LCDSEG1 = leddata[temp1][1];LCDSEG2 = leddata[temp2][0];LCDSEG3 = leddata[temp2][1];LCDSEG6 = 0;LCDSEG7 = 0;   LCDSEG4 = 0;LCDSEG5 = 0;          }
}//***************************************************//
//***************按键读取*******************//
//***************************************************//
unsigned char key1_driver()//P20
{static unsigned char  key1_state = 0;//按键状态变量static unsigned int key_time  = 0;//按键计时变量unsigned char key_return=KEY1_NONE;// 清除 返回按键值switch(key1_state){case KEY1_STATE_0:// 按键状态0:判断有无按键按下if(!P20)// 有按键按下{key_time=0; // 清零时间间隔计数key1_state=KEY1_STATE_1;// 然后进入 按键状态1}break;case KEY1_STATE_1: // 按键状态1:软件消抖(确定按键是否有效,而不是误触)。按键有效的定义:按键持续按下超过设定的消抖时间。if(!P20){key_time++; // 一次10msif(key_time>=SINGLE_KEY1_TIME) // 消抖时间{key1_state=KEY1_STATE_2;// 如果按键时间超过 消抖时间,即判定为按下的按键有效。按键有效包括两种:单击或者双击,进入按键状态2, 继续判定到底是那种有效按键}}elsekey1_state=KEY1_STATE_0; // 如果按键时间没有超过,判定为误触,按键无效,返回 按键状态0,继续等待按键break;case KEY2_STATE_2:if(P20){key_return=KEY1_SHORT;// 返回 有效键值值:单击key1_state=KEY1_STATE_0;// 返回 按键状态0,继续等待按键}break;default: // 特殊情况:key_state是其他值得情况,清零key_state。key1_state=KEY1_STATE_0;break;     }   return key_return;// 返回 按键值
}
unsigned char key1_read()//P20
{static unsigned char  key1_state1 = 0;static unsigned int key_time1  = 0;    unsigned char key_return,key_temp;key_return=KEY1_NONE;// 清零 返回按键值key_temp=key1_driver();// 读取键值switch (key1_state1){case KEY1_STATE_0:// 按键状态0:等待有效按键(通过 key_driver 返回的有效按键值)if(key_temp == KEY1_SHORT)  // 如果是[单击],不马上返回单击按键值,先进入 按键状态1,判断是否有[双击]的可能{key_time1=0; // 清零计时key1_state1=KEY1_STATE_1;}else// 如果不是单击,直接返回按键值。这里的按键值可能是:[双击],[无效按键]{key_return=key_temp;}break;case KEY1_STATE_1: // 按键状态1:判定是否有[双击]if(key_temp == KEY1_SHORT){key_return=KEY1_DOUBLE; // 返回 有效按键:[双击]key1_state1=KEY1_STATE_0; // 返回 按键状态0,等待新的有效按键}else{key_time1++;// 计数 时间间隔if(key_time1>=KEY1_INTERVAL) // 超过 时间间隔{key_return=KEY1_SHORT; // 返回 有效按键:[单击]key1_state1=KEY1_STATE_0;// 返回 按键状态0,等待新的有效按键}}break;       }return key_return;       // 返回 按键值
}unsigned char key2_driver()//P50
{static unsigned char  key2_state = 0;static unsigned int key2_time  = 0;unsigned char key2_return=KEY2_NONE;switch(key2_state){case KEY2_STATE_0:if(!P50){key2_time=0;key2_state=KEY2_STATE_1;}break;case KEY2_STATE_1:if(!P50){key2_time++;if(key2_time>=SINGLE_KEY2_TIME){key2_state=KEY2_STATE_2;}}elsekey2_state=KEY2_STATE_0;break;case KEY1_STATE_2:if(P50){key2_return=KEY2_SHORT;key2_state=KEY2_STATE_0;}break;    default:key2_state=KEY2_STATE_0;break;     }   return key2_return;
}
unsigned char key2_read()//P50
{static unsigned char  key2_state1 = 0;static unsigned int key2_time1  = 0;   unsigned char key2_return,key2_temp;key2_return=KEY2_NONE;key2_temp=key2_driver();switch (key2_state1){case KEY2_STATE_0:if(key2_temp == KEY2_SHORT){key2_time1=0;key2_state1=KEY2_STATE_1;}else{key2_return=key2_temp;}break;case KEY2_STATE_1:if(key2_temp == KEY2_SHORT){key2_return=KEY2_DOUBLE;key2_state1=KEY2_STATE_0;}else{key2_time1++;if(key2_time1>=KEY2_INTERVAL){key2_return=KEY2_SHORT;key2_state1=KEY2_STATE_0;}}break;       }return key2_return;
}//***************************************************//
//***************功能实现*************//
//***************************************************//
void CLOCK()//P50进入闹钟模式或者串口模式
{if(P50_flag_10ms_key){P50_flag_10ms_key = 0;P50_KeyValue = key2_read();switch(P50_KeyValue){case KEY2_SHORT:flag = ~flag;min_sec=0;//进入闹钟模式的标志位if(!flag){LCD_Display();//返回时钟模式}       break;case KEY2_DOUBLE:flag6=~flag6;//进入串口模式的标志位   if(!flag6){LCD_Display();//返回时钟模式}break;}       }
}void clock_change()//闹钟设置时间
{if(P20_flag_10ms_key && flag){CLOCKINIT();P20_flag_10ms_key = 0;P20_KeyValue=key1_read();switch(P20_KeyValue){case KEY1_DOUBLE:min_sec++;break;            case KEY1_SHORT:if(min_sec>0){flag2=1;}if(min_sec%2==0){ ss3++;if(ss3==10){ss3=0;ss4++;if(ss4==6){ss4=0;}}              }if(min_sec%2==1){ ss1++;if(ss1==10){ss1=0;ss2++;if(ss2==6){ss2=0;} }}  break;      }               }if(flag2){if(ss1==s1&&ss2==s2&&ss3==s3&&ss4==s4){flag3=1;}}
}void clock_warning() //闹钟警报
{   if(flag3)//闹钟时间等于时钟时间的标志位{ if(t1&&flag1<6){   //0.5秒亮一次或灭一次,flag1闪烁三秒六次的标志位t1=0;P21=~P21;flag1++;}         clock_reset();       }
}
void clock_reset() //闹钟复位设置
{if(P20_flag_10ms_key1){P20_flag_10ms_key1 = 0;P20_KeyValue1=key1_read();switch(P20_KeyValue1){case KEY1_SHORT:flag4=1;break;}     if(flag4){ss1=0;ss2=0;ss3=0;ss4=0;flag3=0;flag1=0;flag4=0;flag2=0;min_sec=0;//闹钟清零,警报标志位清零,设置闹钟的按键次数清零}}
}
void CLOCK_SET()//时钟模式进入闹钟模式或者串口模式以及返回时钟模式的函数调用
{LCD_Display();//时钟模式CLOCK();//P50单击进入闹钟显示UART();//P50双击进入串口显示clock_change();//P20设置闹钟时间clock_warning();//闹钟警报以及警报后P20按一次,各标志位清零,闹钟时间清零
}

总结

串口模式可以实现与FPGA的数据收发通信。

单片机时钟和闹钟设置,串口通信相关推荐

  1. 9-《电子入门趣谈》第一章_一切从单片机开始-1.3.6串口通信

    好消息:请在手机淘宝或闲鱼上搜索"电子入门趣谈",有惊喜哦 :) 我把全本电子入门趣谈的电子版(包括科技提升和理论升华部分,共计50余万字)放到上面开始兜售啦,如果您真的喜欢这本书 ...

  2. 使用51单片机采用中断方式进行串口通信的学习记录:

    使用51单片机进行串口通信的学习记录之中断方式: 1.51单片机采用中断方式的串口通信过程及程序分析: 所谓中断方式,就是串口收/发标志位出发中断后,在中断中执行既定操作,可通过函数调用来实现. 接收 ...

  3. 51单片机 时钟显示、设置闹钟功能的实现 (附详细算法思路、proteus电路图)

    功能要求: 1.利用定时器中断实现时钟功能,格式:时-分-秒. 2.实现时钟显示和闹钟设置两个功能的切换. 3.闹钟设置,且限定字符格式(如时针不得超过24等). 4.时钟到达预设值时,闹铃正常响起, ...

  4. 51单片机时钟(闹钟)

    题目要求 用按键设定时钟的时.分.秒.要求用4键方式,即选择.加.减.确认键,选择键用于选择修改起始时.分.秒值,每按一次,被修改数码管顺序移动并闪烁.用+,- 键修改数值,确认键确定修改结束. 用扫 ...

  5. 单片机第13课:串口通信---向计算机发送数据

    JP3接P0口. #include<reg51.h> #define uchar unsigned char uchar flag,num; // void initSer(); void ...

  6. 易语言和c51通信,51单片机与PC上位机串口通信之LED控制

    #include #define uint8 unsigned char #define uint16 unsigned int uint8 receive_buffer[6];            ...

  7. 串口通信-电脑控制单片机点亮LED

    前言 此篇只对各函数功能做通俗易懂的解释,适合初学者理解串口通信的功能. 一.串口通信 1.什么是串口通信 我们使用的usb转串口是经典的串口通信之一,实现了电脑与单片机之间的联系,将程序通过串口从电 ...

  8. 51单片机学习笔记-6串口通信

    6 串口通信 [toc] 注:笔记主要参考B站江科大自化协教学视频"51单片机入门教程-2020版 程序全程纯手打 从零开始入门". 注:工程及代码文件放在了本人的Github仓库 ...

  9. 51单片机:中断系统(外部中断,定时器中断,串口通信)

    目录 中断系统简介: 中断的优先级和嵌套: 8个中断请求源及其优先级: 中断的分别介绍: 1.外部中断0:INT0 2.外部中断1 3.T0和 T1:定时计数器的功能 4.串口中断(串口为什么使用定时 ...

  10. 蓝桥杯单片机串口通信学习提升笔记

    今日得以继续蓝桥杯国赛备赛之旅: 有道是 "不知何事萦怀抱,醒也无聊,醉也无聊,梦也何曾到谢桥." 那我们该如何 让这位诗人纳兰 "再听乐府曲 ,畅解相思苦"呢 ...

最新文章

  1. 海外名校毕业!好不容易凭借超强的面试能力+算法入职的谷歌新员工被批干活太慢,委屈得要哭!作为职场新人该怎么办?...
  2. 最新发现6个高质量网站,让人眼前一亮!
  3. python中使用 protocol buffer(Protobuf)
  4. 通过sqlplus执行*.sql文件时常见的问题总结
  5. 读郭老师推荐书籍--《原则》
  6. 网络光端机产品特点及实际应用范围详解
  7. MIUI10迎来最后一波开发版推送 用户体验再升级
  8. vs2005中的aspnetdb(转)
  9. 数据库修复工具 - DatabaseCompressor 之从9M到900K+
  10. 大数计算器c语言实训报告,C语言计算器设计实验报告.doc
  11. 艾宾浩斯记忆表格excel_艾宾浩斯打卡群第二期邀请函
  12. 【AI视野·今日NLP 自然语言处理论文速览 第三十三期】Thu, 21 Apr 2022
  13. cesium导入骨骼动画
  14. USYD悉尼大学DATA1002 详细作业解析Module6
  15. php获取应用宝app下载连接
  16. Java-学校项目3---类与对象
  17. dhcp应该开启还是关闭(dhcp应该开启还是关闭)
  18. 在 Jenkins 上轻松重用 Tekton 和 Jenkins X
  19. 机器学习常见损失函数,二元交叉熵,类别交叉熵,MSE,稀疏类别交叉熵
  20. ccf-csp 2015春季真题题解

热门文章

  1. 深蓝-视觉slam-第三节习题
  2. 计算机用户密码最长使用期限,电脑Win10系统强制用户定期更新密码的方法
  3. 凡刻(Fenke)FK169机械手表测评
  4. html网页如何将文字排版,【html】文字排版
  5. 自制Anki选择题模板(支持桌面版/移动版)
  6. ps里面的css,今天来为大家介绍PS中的图层样式
  7. 黄帝81难经11-20难
  8. c#锁定Excel工作表和单元格
  9. 7、微信小程序-wxs脚本
  10. 安卓Camera屏幕竖屏适配