久久久久久久999_99精品久久精品一区二区爱城_成人欧美一区二区三区在线播放_国产精品日本一区二区不卡视频_国产午夜视频_欧美精品在线观看免费

 找回密碼
 立即注冊

QQ登錄

只需一步,快速開始

搜索
查看: 5865|回復: 5
打印 上一主題 下一主題
收起左側

單片機8個獨立式鍵盤驅動程序(編程模板)

[復制鏈接]
跳轉到指定樓層
樓主
ID:350104 發表于 2018-11-6 16:26 | 只看該作者 回帖獎勵 |倒序瀏覽 |閱讀模式
  1. #define KEY P1 //鍵盤所連接的I/O接口組定義

  2. /*********************************************************************************************
  3. 函數名:8個獨立式鍵盤驅動程序
  4. 調  用:? = Key ();
  5. 參  數:無
  6. 返回值:unsigned char 鍵值0~8
  7. 結  果:有鍵按下時返回值為鍵值1~8,無鍵按下時返回值為0
  8. 備  注:在主函數中不斷調用
  9. /**********************************************************************************************/
  10. unsigned char Key ( ){ //8個獨立鍵盤處理程序
  11. unsigned char a,b;
  12. KEY = 0xff; //設定鍵盤初始電平狀態
  13. if (KEY != 0xff){ //讀取鍵盤狀態是否改變
  14.    Delay (20); //延時20ms去抖動
  15.    if (KEY != 0xff){ //重新讀取
  16.           a = KEY; //寄存狀態值到a
  17. }
  18.         switch(a){ //鍵盤狀態查表
  19.            case 0xfe: b = 1; break;
  20.            case 0xfd: b = 2; break;
  21.            case 0xfb: b = 3; break;
  22.            case 0xf7: b = 4; break;
  23.            case 0xef: b = 5; break;
  24.            case 0xdf: b = 6; break;
  25.            case 0xbf: b = 7; break;
  26.            case 0x7f: b = 8; break;
  27.            default:   b = 0 ; break;
  28.            }
  29.         }
  30. return (b); //將b中的鍵值代號送入函數返回值
  31. }
  32. /**********************************************************************************************/


  33. /*********************************************************************************************
  34. 程序名:    8位ADC轉換實驗程序

  35.                                                                
  36. /*********************************************************************************************
  37. 說明:
  38. PC串口端設置 [ 4800,8,無,1,無 ]
  39. 將ADC讀出的數值通過串口以十六進制方式顯示。

  40. /*********************************************************************************************/

  41. #include <STC12C2052AD.H> //單片機頭文件
  42. #include <intrins.h>        //51基本運算(包括_nop_空函數)

  43. /*********************************************************************************************
  44. 函數名:毫秒級CPU延時函數
  45. 調  用:DELAY_MS (?);
  46. 參  數:1~65535(參數不可為0)
  47. 返回值:無
  48. 結  果:占用CPU方式延時與參數數值相同的毫秒時間
  49. 備  注:應用于1T單片機時i<600,應用于12T單片機時i<125
  50. /*********************************************************************************************/
  51. void DELAY_MS (unsigned int a){
  52.         unsigned int i;
  53.         while( a-- != 0){
  54.                 for(i = 0; i < 600; i++);
  55.         }
  56. }
  57. /*********************************************************************************************/

  58. /*********************************************************************************************
  59. 函數名:UART串口初始化函數
  60. 調  用:UART_init();
  61. 參  數:無
  62. 返回值:無
  63. 結  果:啟動UART串口接收中斷,允許串口接收,啟動T/C1產生波特率(占用)
  64. 備  注:振蕩晶體為12MHz,PC串口端設置 [ 4800,8,無,1,無 ]
  65. /**********************************************************************************************/
  66. void UART_init (void){
  67.         //EA = 1; //允許總中斷(如不使用中斷,可用//屏蔽)
  68.         //ES = 1; //允許UART串口的中斷

  69.         TMOD = 0x20;        //定時器T/C1工作方式2
  70.         SCON = 0x50;        //串口工作方式1,允許串口接收(SCON = 0x40 時禁止串口接收)
  71.         TH1 = 0xF3;        //定時器初值高8位設置
  72.         TL1 = 0xF3;        //定時器初值低8位設置
  73.         PCON = 0x80;        //波特率倍頻(屏蔽本句波特率為2400)
  74.         TR1 = 1;        //定時器啟動   
  75. }
  76. /**********************************************************************************************/

  77. /*********************************************************************************************
  78. 函數名:UART串口發送函數
  79. 調  用:UART_T (?);
  80. 參  數:需要UART串口發送的數據(8位/1字節)
  81. 返回值:無
  82. 結  果:將參數中的數據發送給UART串口,確認發送完成后退出
  83. 備  注:
  84. /**********************************************************************************************/
  85. void UART_T (unsigned char UART_data){ //定義串口發送數據變量
  86.         SBUF = UART_data;        //將接收的數據發送回去
  87.         while(TI == 0);                //檢查發送中斷標志位
  88.         TI = 0;                        //令發送中斷標志位為0(軟件清零)
  89. }
  90. /**********************************************************************************************/
  91. /*********************************************************************************************
  92. 函數名:8位A/D轉換初始化函數
  93. 調  用:Read (?);
  94. 參  數:輸入的端口(0000 0XXX 其中XXX是設置輸入端口號,可用十進制0~7表示,0表示P1.0,7表示P1.7)
  95. 返回值:無
  96. 結  果:開啟ADC功能并設置ADC的輸入端口
  97. 備  注:適用于STC12C2052AD系列單片機(必須使用STC12C2052AD.h頭文件)
  98. /**********************************************************************************************/
  99. void Read_init (unsigned char CHA){
  100.         unsigned char AD_FIN=0; //存儲A/D轉換標志
  101.     CHA &= 0x07;            //選擇ADC的8個接口中的一個(0000 0111 清0高5位)
  102.     ADC_CONTR = 0x40;                //ADC轉換的速度(0XX0 0000 其中XX控制速度,請根據數據手冊設置)
  103.     _nop_();
  104.     ADC_CONTR |= CHA;       //選擇A/D當前通道
  105.     _nop_();
  106.     ADC_CONTR |= 0x80;      //啟動A/D電源
  107.     DELAY_MS(1);            //使輸入電壓達到穩定(1ms即可)
  108. }
  109. /**********************************************************************************************/
  110. /*********************************************************************************************
  111. 函數名:8位A/D轉換函數
  112. 調  用:? = Read ();
  113. 參  數:無
  114. 返回值:8位的ADC數據
  115. 結  果:讀出指定ADC接口的A/D轉換值,并返回數值
  116. 備  注:適用于STC12C2052AD系列單片機(必須使用STC12C2052AD.h頭文件)
  117. /**********************************************************************************************/
  118. unsigned char Read (void){
  119.         unsigned char AD_FIN=0; //存儲A/D轉換標志
  120.     ADC_CONTR |= 0x08;      //啟動A/D轉換(0000 1000 令ADCS = 1)
  121.     _nop_();
  122.     _nop_();
  123.     _nop_();
  124.     _nop_();
  125.     while (AD_FIN ==0){     //等待A/D轉換結束
  126.         AD_FIN = (ADC_CONTR & 0x10); //0001 0000測試A/D轉換結束否
  127.     }
  128.     ADC_CONTR &= 0xE7;      //1111 0111 清ADC_FLAG位, 關閉A/D轉換,
  129. return (ADC_DATA);          //返回A/D轉換結果(8位)
  130. }
  131. /**********************************************************************************************/
  132. /*********************************************************************************************
  133. 函數名:主函數
  134. 調  用:無
  135. 參  數:無
  136. 返回值:無
  137. 結  果:程序開始處,無限循環
  138. 備  注:
  139. /**********************************************************************************************/
  140. void main (void){
  141.         unsigned char R;
  142.         UART_init();//串口初始程序
  143.         Read_init(0);//ADC初始化
  144.         P1M0 = 0x01; //P1.7~.0:0000 0001(高阻)//注意:更改ADC通道時須同時將對應的IO接口修改為高阻輸入。
  145.         P1M1 = 0x00; //P1.7~.0:0000 0000(強推)
  146.         while(1){
  147.             R = Read ();
  148.             UART_T (R); //串口小秘書,將ADC讀出值送入串口顯示
  149.         }
  150. }/**********************************************************************************************/

  151. #define KEY P1 //鍵盤所連接的I/O接口組定義

  152. /*********************************************************************************************
  153. 函數名:16個陣列式鍵盤驅動程序
  154. 調  用:? = Key ();
  155. 參  數:無
  156. 返回值:unsigned char 鍵值0~16
  157. 結  果:有鍵按下時返回值為鍵值1~16,無鍵按下時返回值為0
  158. 備  注:在主函數中不斷調用
  159. /**********************************************************************************************/
  160. unsigned char Key (void){ //4*4陣列鍵盤處理程序
  161. unsigned char a,b,c;
  162. KEY = 0x0f; //設定鍵盤初始電平狀態
  163. if (KEY != 0x0f){ //讀取鍵盤狀態是否改變
  164.    Delay (20); //延時20ms去抖動
  165.    if (KEY != 0x0f){ //重新讀取
  166.           a = KEY; //寄存狀態值到a
  167.         }
  168.         KEY = 0xf0; //設定鍵盤反向電平狀態
  169.         c = KEY; //讀取反向電平狀態值到c
  170.         a = a|c; //a與c相或
  171.         switch(a){ //鍵盤狀態查表
  172.            case 0xee: b = 1; break;
  173.            case 0xed: b = 2; break;
  174.            case 0xeb: b = 3; break;
  175.            case 0xe7: b = 4; break;
  176.            case 0xde: b = 5; break;
  177.            case 0xdd: b = 6; break;
  178.            case 0xdb: b = 7; break;
  179.            case 0xd7: b = 8; break;
  180.            case 0xbe: b = 9; break;
  181.            case 0xbd: b = 10; break;
  182.            case 0xbb: b = 11; break;
  183.            case 0xb7: b = 12; break;
  184.            case 0x7e: b = 13; break;
  185.            case 0x7d: b = 14; break;
  186.            case 0x7b: b = 15; break;
  187.            case 0x77: b = 16; break;
  188.            default:   b = 0 ; break;
  189.            }
  190.         }
  191. return (b); //將b中的鍵值代號送入函數返回值
  192. }
  193. /**********************************************************************************************/

  194. /*********************************************************************************************
  195. 程序名:STC系列單片機內部EEPROM 測試程序
  196. P1口接8個LED到VCC。
  197. 適用硬件:
  198. STC12C5AxxAD系列單片機
  199. STC12C52xxAD系列單片機
  200. STC11xx系列單片機
  201. STC10xx系列單片機
  202. 使用說明:
  203. 1,程序先別P1口高4位和低4位分別點亮一次。
  204. 2,檢查EEPROM中對應地址內的值是否與用戶測試值相同。
  205. 3,如果相同則P1.7上的LED亮,然后在P1口顯示EEPROM中的值。
  206. 4,如果不同則P1.3上的LED亮,然后全片擦除EEPROM并寫入用戶測試值到指定地址。
  207. 注意:
  208. # 在第一次下載時為寫入(第4步),復位后才會測試。
  209. # 當供電電源低于一定值時將不能寫入EEPROM,詳見數據手冊。


  210. /*********************************************************************************************/
  211. #include <reg51.H>
  212. #include <intrins.H>
  213. /*********************************************************************************************/
  214. typedef unsigned char  INT8U;
  215. typedef unsigned int   INT16U;
  216. /*********************************************************************************************/
  217. //用于STC12C2052系列單片機時選擇//
  218. sfr IAP_DATA    = 0xE2; //STC12C2052系列單片機的EEPRON操作地址是0xe2(以下類推)
  219. sfr IAP_ADDRH   = 0xE3;
  220. sfr IAP_ADDRL   = 0xE4;
  221. sfr IAP_CMD     = 0xE5;
  222. sfr IAP_TRIG    = 0xE6;
  223. sfr IAP_CONTR   = 0xE7;
  224. #define WD1        0x46        //使用STC12C2052系列單片機時,先寫入0x46,然寫入0xb9
  225. #define WD2        0xb9
  226. /*********************************************************************************************
  227. //用于STC11/10xx系列單片機時選擇//
  228. sfr IAP_DATA    = 0xC2; //STC11xx系列單片機的EEPRON操作地址是0xc2(以下類推)
  229. sfr IAP_ADDRH   = 0xC3;
  230. sfr IAP_ADDRL   = 0xC4;
  231. sfr IAP_CMD     = 0xC5;
  232. sfr IAP_TRIG    = 0xC6;
  233. sfr IAP_CONTR   = 0xC7;
  234. #define WD1        0x5a        //使用STC11xx系列單片機時,先寫入0x5a,然寫入0xa5
  235. #define WD2        0xa5
  236. /*********************************************************************************************/
  237. //定義Flash 操作等待時間及允許IAP/ISP/EEPROM 操作的常數//
  238. //#define ENABLE_ISP 0x80 //系統工作時鐘<30MHz 時,對IAP_CONTR 寄存器設置此值
  239. //#define ENABLE_ISP 0x81 //系統工作時鐘<24MHz 時,對IAP_CONTR 寄存器設置此值
  240. #define ENABLE_ISP 0x82 //系統工作時鐘<20MHz 時,對IAP_CONTR 寄存器設置此值
  241. //#define ENABLE_ISP 0x83 //系統工作時鐘<12MHz 時,對IAP_CONTR 寄存器設置此值
  242. //#define ENABLE_ISP 0x84 //系統工作時鐘<6MHz 時,對IAP_CONTR 寄存器設置此值
  243. //#define ENABLE_ISP 0x85 //系統工作時鐘<3MHz 時,對IAP_CONTR 寄存器設置此值
  244. //#define ENABLE_ISP 0x86 //系統工作時鐘<2MHz 時,對IAP_CONTR 寄存器設置此值
  245. //#define ENABLE_ISP 0x87 //系統工作時鐘<1MHz 時,對IAP_CONTR 寄存器設置此值
  246. /*********************************************************************************************/
  247. #define DEBUG_DATA               0x55  //存儲在 EEPROM 單元的數值(用戶可修改測試)
  248. #define DATA_FLASH_START_ADDRESS 0x00  //EEPROM存入地址(用戶可修改測試)
  249. /*********************************************************************************************/
  250. union union_temp16
  251. {
  252.     INT16U un_temp16;
  253.     INT8U  un_temp8[2];
  254. }my_unTemp16;

  255. INT8U Byte_Read(INT16U add);              //讀一字節,調用前需打開IAP 功能
  256. void Byte_Program(INT16U add, INT8U ch);  //字節編程,調用前需打開IAP 功能
  257. void Sector_Erase(INT16U add);            //擦除扇區
  258. void IAP_Disable();                       //關閉IAP 功能
  259. void Delay();
  260. /*********************************************************************************************/
  261. void main (void)
  262. {
  263.     INT16U eeprom_address;
  264.     INT8U  read_eeprom;

  265.     P1 = 0xF0;                            //演示程序開始,讓 P1[3:0] 控制的燈亮
  266.     Delay();                              //延時
  267.     P1 = 0x0F;                            //演示程序開始,讓 P1[7:4] 控制的燈亮
  268.     Delay()    ;                          //延時

  269.     //將EEPROM 測試起始地址單元的內容讀出
  270.     eeprom_address = DATA_FLASH_START_ADDRESS;  //將測試起始地址送eeprom_address
  271.     read_eeprom = Byte_Read(eeprom_address);    //讀EEPROM的值,存到read_eeprom

  272.     if (DEBUG_DATA == read_eeprom)
  273.     {   //數據是對的,亮  P1.7 控制的燈,然后在 P1 口上將 EEPROM 的數據顯示出來
  274.         P1 = ~0x80;
  275.         Delay()    ;                            //延時
  276.         P1 = ~read_eeprom;
  277.     }
  278.     else
  279.     {   //數據是錯的,亮 P1.3 控制的燈,然后在 P1 口上將 EEPROM 的數據顯示出來
  280.         //再將該EEPROM所在的扇區整個擦除,將正確的數據寫入后,亮 P1.5 控制的燈
  281.         P1 = ~0x08;
  282.         Delay()    ;                            //延時
  283.         P1 = ~read_eeprom;
  284.         Delay()    ;                            //延時

  285.         Sector_Erase(eeprom_address);           //擦除整個扇區
  286.         Byte_Program(eeprom_address, DEBUG_DATA);//將 DEBUG_DATA 寫入 EEPROM

  287.         P1 = ~0x20;                 //熄滅 P1.3 控制的燈,亮 P1.5 控制的燈
  288.     }

  289.     while (1);                      //CPU 在此無限循環執行此句
  290. }
  291. /*********************************************************************************************/
  292. //讀一字節,調用前需打開IAP 功能,入口:DPTR = 字節地址,返回:A = 讀出字節
  293. INT8U Byte_Read(INT16U add)
  294. {
  295.     IAP_DATA = 0x00;
  296.     IAP_CONTR = ENABLE_ISP;         //打開IAP 功能, 設置Flash 操作等待時間
  297.     IAP_CMD = 0x01;                 //IAP/ISP/EEPROM 字節讀命令

  298.     my_unTemp16.un_temp16 = add;
  299.     IAP_ADDRH = my_unTemp16.un_temp8[0];    //設置目標單元地址的高8 位地址
  300.     IAP_ADDRL = my_unTemp16.un_temp8[1];    //設置目標單元地址的低8 位地址

  301.     //EA = 0;
  302.     IAP_TRIG = WD1;   //先送 WD1,再送WD2 到ISP/IAP 觸發寄存器,每次都需如此
  303.     IAP_TRIG = WD2;   //送完WD2 后,ISP/IAP 命令立即被觸發起動
  304.     _nop_();
  305.     //EA = 1;
  306.     IAP_Disable();  //關閉IAP 功能, 清相關的特殊功能寄存器,使CPU 處于安全狀態,
  307.                     //一次連續的IAP 操作完成之后建議關閉IAP 功能,不需要每次都關
  308.     return (IAP_DATA);
  309. }
  310. /*********************************************************************************************/
  311. //字節編程,調用前需打開IAP 功能,入口:DPTR = 字節地址, A= 須編程字節的數據
  312. void Byte_Program(INT16U add, INT8U ch)
  313. {
  314.     IAP_CONTR = ENABLE_ISP;         //打開 IAP 功能, 設置Flash 操作等待時間
  315.     IAP_CMD = 0x02;                 //IAP/ISP/EEPROM 字節編程命令

  316.     my_unTemp16.un_temp16 = add;
  317.     IAP_ADDRH = my_unTemp16.un_temp8[0];    //設置目標單元地址的高8 位地址
  318.     IAP_ADDRL = my_unTemp16.un_temp8[1];    //設置目標單元地址的低8 位地址

  319.     IAP_DATA = ch;                  //要編程的數據先送進IAP_DATA 寄存器
  320.     //EA = 0;
  321.     IAP_TRIG = WD1;   //先送 WD1,再送WD2 到ISP/IAP 觸發寄存器,每次都需如此
  322.     IAP_TRIG = WD2;   //送完WD2 后,ISP/IAP 命令立即被觸發起動
  323.     _nop_();
  324.     //EA = 1;
  325.     IAP_Disable();  //關閉IAP 功能, 清相關的特殊功能寄存器,使CPU 處于安全狀態,
  326.                     //一次連續的IAP 操作完成之后建議關閉IAP 功能,不需要每次都關
  327. }
  328. /*********************************************************************************************/
  329. //擦除扇區, 入口:DPTR = 扇區地址
  330. void Sector_Erase(INT16U add)
  331. {
  332.     IAP_CONTR = ENABLE_ISP;         //打開IAP 功能, 設置Flash 操作等待時間
  333.     IAP_CMD = 0x03;                 //IAP/ISP/EEPROM 扇區擦除命令

  334.     my_unTemp16.un_temp16 = add;
  335.     IAP_ADDRH = my_unTemp16.un_temp8[0];    //設置目標單元地址的高8 位地址
  336.     IAP_ADDRL = my_unTemp16.un_temp8[1];    //設置目標單元地址的低8 位地址

  337.     //EA = 0;
  338.     IAP_TRIG = WD1;   //先送 WD1,再送WD2 到ISP/IAP 觸發寄存器,每次都需如此
  339.     IAP_TRIG = WD2;   //送完WD2 后,ISP/IAP 命令立即被觸發起動
  340.     _nop_();
  341.     //EA = 1;
  342.     IAP_Disable();  //關閉IAP 功能, 清相關的特殊功能寄存器,使CPU 處于安全狀態,
  343.                     //一次連續的IAP 操作完成之后建議關閉IAP 功能,不需要每次都關
  344. }
  345. /*********************************************************************************************/
  346. void IAP_Disable()
  347. {
  348.     //關閉IAP 功能, 清相關的特殊功能寄存器,使CPU 處于安全狀態,
  349.     //一次連續的IAP 操作完成之后建議關閉IAP 功能,不需要每次都關
  350.     IAP_CONTR = 0;      //關閉IAP 功能
  351.     IAP_CMD   = 0;      //清命令寄存器,使命令寄存器無命令,此句可不用
  352.     IAP_TRIG  = 0;      //清命令觸發寄存器,使命令觸發寄存器無觸發,此句可不用
  353.     IAP_ADDRH = 0;
  354.     IAP_ADDRL = 0;
  355. }
  356. /*********************************************************************************************/
  357. void Delay() //延時程序
  358. {
  359.     INT8U i;
  360.     INT16U d=5000;
  361.     while (d--)
  362.     {
  363.         i=255;
  364.         while (i--);
  365.     }
  366. }




復制代碼

評分

參與人數 1黑幣 +50 收起 理由
admin + 50 共享資料的黑幣獎勵!

查看全部評分

分享到:  QQ好友和群QQ好友和群 QQ空間QQ空間 騰訊微博騰訊微博 騰訊朋友騰訊朋友
收藏收藏 分享淘帖 頂 踩
回復

使用道具 舉報

沙發
ID:1 發表于 2018-11-6 18:46 | 只看該作者
補全原理圖或者詳細說明一下電路連接即可獲得100+黑幣
回復

使用道具 舉報

板凳
ID:350104 發表于 2018-11-8 11:57 | 只看該作者
admin 發表于 2018-11-6 18:46
補全原理圖或者詳細說明一下電路連接即可獲得100+黑幣

這個是模板 萬能使用 只要結合自己的電路修改相應的端口就可以了 很方便使用的
回復

使用道具 舉報

地板
ID:350104 發表于 2018-11-8 15:00 | 只看該作者
admin 發表于 2018-11-6 18:46
補全原理圖或者詳細說明一下電路連接即可獲得100+黑幣

這個是萬能編程模板 只要根據自己的電路圖 改改端口就能用
回復

使用道具 舉報

5#
ID:399179 發表于 2018-11-8 18:26 來自手機 | 只看該作者
感謝分享!
回復

使用道具 舉報

6#
ID:66287 發表于 2018-11-9 08:59 | 只看該作者
是有用的東東,謝謝分享!
回復

使用道具 舉報

您需要登錄后才可以回帖 登錄 | 立即注冊

本版積分規則

手機版|小黑屋|51黑電子論壇 |51黑電子論壇6群 QQ 管理員QQ:125739409;技術交流QQ群281945664

Powered by 單片機教程網

快速回復 返回頂部 返回列表
主站蜘蛛池模板: 亚洲导航深夜福利涩涩屋 | 国产美女一区二区 | 国产精品一区二区av | 欧美日韩在线观看视频 | 亚洲毛片 | 日本精品一区二区 | 99精品99 | 亚洲精品小视频在线观看 | 国产精品成人一区二区三区夜夜夜 | 国产一区二区在线免费观看 | 午夜精品久久久久久久久久久久 | www.青娱乐 | 亚洲成人精品在线 | 亚洲 欧美 激情 另类 校园 | 国产91久久久久蜜臀青青天草二 | 久久亚洲视频网 | 久久一区二区三区免费 | 你懂的国产 | 午夜影院在线视频 | 一二三四在线视频观看社区 | 亚洲精品视频在线播放 | 日本高清中文字幕 | 看片国产| 国产第一亚洲 | 国产一区二区三区四区区 | 久久手机在线视频 | 在线一级片 | 一级毛片观看 | 久青草影院 | 国产一区二区三区四区 | 精品一区二区在线看 | 看片wwwwwwwwwww| 成人免费观看视频 | 天堂色| 成年人在线观看视频 | 国产精品久久 | 久久久精品网站 | 国产免费又黄又爽又刺激蜜月al | 中文在线播放 | 91精品久久久久久久99 | 四虎成人精品永久免费av九九 |