找回密码
 立即注册

QQ登录

只需一步,快速开始

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

单片机控制三个独立按键,长按加减键四位数码管就显示0000

[复制链接]
跳转到指定楼层
楼主
ID:598951 发表于 2019-8-20 18:07 | 只看该作者 回帖奖励 |倒序浏览 |阅读模式
本帖最后由 fmdpj 于 2019-8-20 21:21 编辑

小白求助高手,在网上找到的FM发射控制程序,三个独立按键分别是频率加减键与立体声开关,加减键是短按步进0.1MHz,长按自动加减,释放停止加减,刚开始是一按加减键四位数码管就显示0000,按键也同时失效,后来把消抖延时加长到8000(原300)短按加减键会再显示0000可以正常加减,但是长按还是不正常,长按可以加减10到20秒就又显示0000按键同时失效,求高手指点

下面是源代码,请高手帮忙看看程序那里有问题,应该怎样改,谢谢!
  1. //使用AT89S52单片机,12MHz晶振,使用4位共阳数码管作为频率显示。
  2. //P1口输出段码,P2口扫描。
  3. //频率范围87.5MHz--108.0MHz
  4. //***********************************************************************
  5. #include  <reg52.h>
  6. #include  <intrins.h>       //_nop_();延时函数调用                 
  7. #define    LED_DATA   P1            // 数码管段码输出
  8. #define    LED_WEI    P2          // 数码管位码输出,扫描口
  9. #define    uchar unsigned  char
  10. #define    uint unsigned  int
  11. sbit      key_fr_up      =P2^3;          //频率增加键
  12. sbit      key_fr_down    =P2^2;          //频率递减键
  13. sbit      key_LTS_KZ     =P2^1;          //立体声控制键
  14. sbit      LTS_LED        =P3^3;          //立体声显示//INT1
  15. sbit      CE             =P3^4;          //锁存信号//CE
  16. sbit      CLK            =P3^5;        //时钟信号//CLK
  17. sbit      DA             =P3^6;          //数据信号//DA
  18. sbit      dg             =P1^7;        //数码管小数点                           
  19. //sbit SDA=P3^2;//24C01 数据线
  20. //sbit SCL=P3^1;//24c01 时钟线


  21. uint      f_data;          //频率数值
  22. //uchar DataBye;//从24C01中读出的暂时存储区

  23. bit        modo;     //立体声数据寄存器
  24. uchar      key_temp;       //键盘有键按下标志位
  25. uint  i;
  26. uchar code DATA[11]={0xC0,0xF9,0xA4,0xB0,0x99,0x92,0x82,0xF8,0x80,0x90,0xFF};
  27. //数码管显示字0-9,不显示
  28. uchar  code   WEI[4]={0x1f,0x2f,0x4f,0x8f};    //数码管扫描控制
  29. uchar  data    display[4]={0x00,0x00,0x00,0x00};  //数码管显示数据缓冲区
  30. //************************延时函数1******************************
  31. void Delay1(void)
  32. {
  33. _nop_();
  34. _nop_();
  35. _nop_();
  36. _nop_();
  37. }
  38. ///***********************延时函数***********************************
  39. void  delay(uint t)
  40. {
  41. for(;t>0;t--);
  42. }
  43. ///***************************显示函数******************************
  44. ///        4位数码管动态扫描
  45. ///*****************************************************************
  46. void  xianshi(void)
  47. {
  48. uchar k;
  49. for(k=0;k<4;k++)                    //4位数码管显示
  50. {
  51. LED_DATA=DATA[display[k]];      
  52. LED_WEI=WEI[k];          //先显示百位
  53. if(k==2){ dg=0; }                    //显示小数点
  54. delay(35);
  55. }
  56. LED_DATA=0xff;                  //清除显示
  57. }
  58. ///*************************显示数值处理函数***************************
  59. //*********************************************************************
  60. void xianshi_turn(void)                  //频率数据转换为显示用BCD码函数
  61. {
  62. uint fr;
  63. display[0]=f_data/1000;                //求显示百位数
  64. if(display[0]==0)
  65. {
  66. display[0]=10;
  67. }                                          
  68. fr=f_data%1000;
  69. display[1]=fr/100;                //求显示十位数
  70. fr=fr%100;   
  71. display[2]=fr/10;                //求显示个位数
  72. display[3]=fr%10;                //求显示小数位
  73. }
  74. //***********************综合显示函数*********************************
  75. //********************************************************************
  76. void  T_Display(void)
  77. {
  78. xianshi_turn();
  79. xianshi();
  80. }
  81. ///*************************写数据函数*********************************
  82. //将数据送入BH1415中
  83. //*********************************************************************
  84. void send_16data(uint Data,uchar MODO)
  85. {
  86. uchar i;
  87. CLK=0;
  88. CE=0;
  89. CE=1;  //连续保存高电平,可输入数据
  90. for(i=11;i>0;i--)
  91. {
  92. DA=Data & 0x01;
  93. //传输BH1415F2个字节频率控制11位D0-D10频率数据
  94. Data>>=1;
  95. Delay1();
  96. CLK=1;
  97. Delay1();
  98. CLK=0;
  99. }
  100. DA=MODO;
  101. Delay1();
  102. CLK=1;   //MONO
  103. Delay1();
  104. CLK=0;
  105. Delay1();
  106. DA=0;
  107. Delay1();  //PD0
  108. CLK=1;   
  109. Delay1();
  110. CLK=0;
  111. Delay1();
  112. DA=0;
  113. Delay1();  //PD1
  114. CLK=1;  
  115. Delay1();  
  116. CLK=0;   
  117. Delay1();
  118. DA=1;
  119. Delay1();  //测试模式控制关闭
  120. CLK=1;   
  121. Delay1();
  122. CLK=0;
  123. Delay1();
  124. DA=0;
  125. Delay1();  //测试模式控制关闭
  126. CLK=1;   
  127. Delay1();
  128. CLK=0;
  129. CE=0;       //输入数据结束
  130. }
  131. //*************************键盘处理函数*************************//
  132. //
  133. //
  134. //****************************************************************
  135. void KEY(void)
  136. {
  137. uint ii=0,jj=0;  //记录频率增加的个数,若ii>4,f以5为增量增加
  138. uchar key_data;  //若jj>4,f以5为增量减小
  139. P2=0x0F;
  140. P1=0x0F;  //键盘扫描口断码输出初始化//

  141. if((P2&0x0F)!=0x0F)
  142. {
  143. delayms(10);            
  144. if((P2&0x0F)!=0x0F)       //防抖动测试                           
  145. {   
  146. key_temp=1;      //键盘有键按下标志位//                              
  147. key_data=P2&0x0F;
  148. switch(key_data)
  149. {
  150. case  0x07:              //频率自动加//
  151. {
  152. f_data++;
  153. if(f_data>1080)
  154. f_data=875;
  155. T_Display();
  156. while(key_fr_up==0)                     
  157. {
  158. for(i=400;i>0;i--)  //设置等待自动加频率的时间
  159. {
  160. delay(50);
  161. if(key_fr_up==1)break;   
  162. }
  163. while(key_fr_up==0) //开始自动加频率   
  164. {
  165. f_data++;
  166. ii++;
  167. if(ii>4)f_data+=5;
  168. if(f_data>1080)f_data=875;
  169. T_Display();
  170. for(i=110;i>0;i--)   //设置长时间按键
  171. //后,自动加数字的速度//
  172. {
  173. delay(25);
  174. if(key_fr_up==1)break;
  175. }
  176. }
  177. }
  178. break;
  179. }
  180. case 0x0B://频率自动减//
  181. {
  182. f_data--;
  183. if(f_data<875)f_data=1080;
  184. T_Display();
  185. while(key_fr_down==0)
  186. {
  187. for(i=400;i>0;i--) //设置等待自动减频率的时间
  188. {
  189. delay(50);
  190. if(key_fr_down==1)break;
  191. }
  192. while(key_fr_down==0) //开始自动减频率
  193. {
  194. f_data--;
  195. ii++;
  196. if(ii>4) f_data-=5;
  197. if(f_data<875) f_data=1080;
  198. T_Display();
  199. for(i=110;i>0;i--)  //设置长时间按键后,自动减数字的速度//
  200. {
  201. delay(25);
  202. if(key_fr_down==1) break;
  203. }
  204. }
  205. }
  206. break;
  207. }
  208. case 0x0D:   //立体声控制
  209. {
  210. if(key_LTS_KZ==0)
  211. {
  212. modo=~modo;
  213. LTS_LED=~modo;  //打开关闭立体声
  214. //WriteIIC_24C01(0x02,modo);
  215. }
  216. while(key_LTS_KZ==0);
  217. break;
  218. }
  219. default:
  220. {
  221. key_temp=0;
  222. break;
  223. }
  224. }
  225. }
  226.   else  
  227. key_temp=0;
  228. }
  229. else  
  230. key_temp=0;
  231. }
  232. //**************************初始化程序**********************************//
  233. void CSH (void)
  234. { uint i;
  235. CE=0;
  236. CLK=0;
  237. DA=0;
  238. P2=0x0F;
  239. P1=0x0FF;    //键盘接口、扫描口、段码输出口初始化
  240. for(i=0;i<4;i++)      //开机
  241. display[i]=8;         //显示
  242. for(i=0;i<500;i++)    //显示
  243. xianshi();           //显示8888
  244. f_data=875;
  245. modo=1;//立体声关闭
  246. key_temp=0;
  247. }
  248. //***************************主程序MAIN()*******************************
  249. //TMOD:定时/计数器方式控制寄存器
  250. //TH0 TL0:定时计数器0
  251. //TR0:定时计数器0工作启停位
  252. //ET0:定时计数器0允许中断位
  253. //EA:中断允许/禁止位
  254. //***********************************************************************
  255. main()
  256. {
  257. CSH();//开机初始化
  258. delay(50);
  259. //modo=(bit)(DataByte);
  260. delay(50);
  261. send_16data(f_data,modo);  //向1415送初始数据
  262. //DENGDAI();
  263. LTS_LED=~modo;  //立体声打开
  264. TMOD=0x01;  //定时计数器0工作方式1,16位自动启动方式
  265. TH0=0xEA;
  266. TL0=0xD0;                                                                                                   
  267. TR0=1;
  268. ET0=1;
  269. EA=1; //开中断
  270. while(1) //启动键盘处理程序,同时等待中断
  271. {
  272. KEY();
  273. } //启动键盘处理程序,同时等待中断
  274. }
  275. //*****************************中断服务程序******************************
  276. //5.424ms中断一次
  277. //***********************************************************************
  278. void t0(void) interrupt 1 using 0
  279. {
  280. ET0=0;
  281. if(key_temp==1)
  282. {
  283. send_16data(f_data,modo); //向BH1415F发送数据
  284. }
  285. key_temp=0;
  286. xianshi_turn(); //显示数据转换
  287. xianshi();   
  288. key_temp=1;
  289. TH0=0xEA;
  290. TL0=0xD0;
  291. ET0=1;
  292. }
复制代码

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

使用道具 举报

沙发
ID:213173 发表于 2019-8-21 08:15 | 只看该作者
楼主的数码管位码和按键分别用了P2口的高4位和低4位,但是程序中并没有把P2口的高4位和低4位隔离操作,也没有分时操作。混在一起操作当然玩不转。
回复

使用道具 举报

板凳
ID:598951 发表于 2019-8-21 20:24 | 只看该作者
wulin 发表于 2019-8-21 08:15
楼主的数码管位码和按键分别用了P2口的高4位和低4位,但是程序中并没有把P2口的高4位和低4位隔离操作,也没 ...

要怎样修改呢,
回复

使用道具 举报

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

本版积分规则

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

Powered by 单片机教程网

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