写在前面

尝试自己按照用户手册,写库函数,写应用测试

平台

STC8G1K08核心板
image.png

LED

测试代码

  1. #include <STC8G.H>
  2. /******************** IO配置函数 **************************/
  3. void LED_Init(void)
  4. {
  5. P5M1 = 0x00; //LED引脚P55
  6. P5M0 = 0x00; //00设置准双向口 01推挽输出 10高阻输入 11开漏输出
  7. }
  8. void LED_ON(void)
  9. {
  10. P55 = 0;
  11. }
  12. void LED_OFF(void)
  13. {
  14. P55 = 1;
  15. }
  1. #ifndef __LED_H
  2. #define __LED_H
  3. void LED_Init(void);
  4. void LED_ON(void);
  5. void LED_OFF(void);
  6. #endif

芯片手册

image.png
image.png

KEY

测试代码

  1. #include <STC8G.H>
  2. /******************** IO配置函数 **************************/
  3. void KEY_Init(void)
  4. {
  5. P1M0 = 0x00; //设置双向输入,P1.0为输入高阻
  6. P1M1 = 0x01;
  7. }
  1. #ifndef __KEY_H
  2. #define __KEY_H
  3. void KEY_Init(void);
  4. #endif

芯片手册

image.png

ADC

测试代码

  1. #include <STC8G.H>
  2. #include "intrins.h"
  3. /******************** IO配置函数 **************************/
  4. void ADC_Init(void)
  5. {
  6. P1M0 = 0x00; //设置双向输入,P1.0为输入高阻
  7. P1M1 = 0x01;
  8. P_SW2 |= 0x80; //P_SW2:外设端口切换寄存器2 与0x80取|后,相当于把寄存器末位EAXFR置1
  9. //特殊功能寄存器为扩展SFR,逻辑地址位于 XDATA 区域,访问前需要将 P_SW2(BAH)寄存器的最高位(EAXFR)置 1
  10. //ADCTIM就是特殊功能寄存器
  11. ADCTIM = 0x3f; //设置 ADC 内部时序
  12. //0011 1111 ADC通道选择时间1 ADC通道选择保持时间2 ADC模拟信号采样时间32
  13. P_SW2 &= 0x7f; //P_SW2:外设端口切换寄存器2 与0x7f取&后,相当于把寄存器末位EAXFR置0
  14. ADCCFG = 0x0f; //设置 ADC 时钟为系统时钟/2/16/16
  15. //0000 1111
  16. //0000 转换结果左对齐
  17. //1111 SYSclk/2/16
  18. ADC_CONTR = 0x80; //使能 ADC 模块
  19. //1000 0000
  20. //1000 打开ADC电源
  21. }
  22. int analogRead(int channel)
  23. {
  24. int res = 0;
  25. ADC_CONTR &= 0xf0; //底四位清零
  26. //1111 0000
  27. //1111 打开ADC电源;开始ADC转换,转换完成后硬件自动将此位清零;
  28. //0000 ADC模拟通道选择位P10
  29. ADC_CONTR |= channel; //置位通道
  30. ADC_CONTR |= 0x40; //启动AD转换 0100 0000开始ADC转换
  31. _nop_();
  32. _nop_();
  33. while (!(ADC_CONTR & 0x20)); //查询 ADC 完成标志
  34. ADC_CONTR &= ~0x20; //清完成标志 ADC_FLAG:ADC 转换结束标志位,
  35. //当 ADC 完成一次转换后,硬件会自动将此位置 1,并向 CPU 提出中断请求,此标志位必须软件清零。
  36. res = (int)(ADC_RES*4); //觉得应该右移两位才对?
  37. res += ADC_RESL;
  38. return res; //读取 ADC 结果
  39. }
  1. #ifndef __ADC_H
  2. #define __ADC_H
  3. void ADC_Init(void);
  4. int analogRead(int channel);
  5. #endif
  1. #include <STC8G.h>
  2. #include "intrins.h"
  3. #include "Delay.h"
  4. #include "config.h"
  5. #include "LED.h"
  6. #include "KEY.h"
  7. #include "ADC.h"
  8. int advalue = 0;
  9. void main(void)
  10. {
  11. LED_Init();
  12. ADC_Init();
  13. while(1)
  14. {
  15. advalue = analogRead(0);
  16. if(advalue > 1000)
  17. {
  18. LED_ON();
  19. }
  20. else
  21. {
  22. LED_OFF();
  23. }
  24. }
  25. }

芯片手册

image.png
image.png

UART

测试代码

  1. #include <STC8G.H>
  2. #include "UART.h"
  3. bit busy;
  4. char wptr;
  5. char buffer;
  6. u8 UART_RxFlag;
  7. void UART_Init()
  8. {
  9. P1M0 = 0x00; //P10 P11 设置准双向口 串口2
  10. P1M1 = 0x00;
  11. P3M0 = 0x00; //P30 P31 设置准双向口 串口1
  12. P3M1 = 0x00;
  13. SCON = 0x50; //串口1控制寄存器 0101 0000 模式1 允许串口接收
  14. T2L = BRT; //定时器2低字节 属于特殊功能寄存器
  15. T2H = BRT >> 8;
  16. AUXR = 0x15; //AUXR定时器2辅助寄存器1 0001 0101 定时器2开始计数;用作定时器
  17. wptr = 0x00;
  18. // rptr = 0x00;
  19. busy = 0;
  20. ES = 1; //ES:串行口1中断允许位
  21. EA = 1; //EA:总中断允许控制位
  22. }
  23. void UART_SendChar(unsigned char dat) //发送一个字符
  24. {
  25. while (busy);
  26. busy = 1;
  27. SBUF = dat;
  28. }
  29. void UART_SendString(unsigned char *p) //发送字符串
  30. {
  31. while (*p)
  32. {
  33. UART_SendChar(*p++);
  34. }
  35. }
  36. //重写putchar函数
  37. char putchar(char c)
  38. {
  39. UART_SendChar(c);
  40. return c;
  41. }
  42. //串口接收标志位
  43. u8 UART_GetRxFlag(void)
  44. {
  45. if (UART_RxFlag == 1)
  46. {
  47. UART_RxFlag = 0;
  48. return 1;
  49. }
  50. return 0;
  51. }
  52. //串口接收数据
  53. u8 UART_GetRxData(void)
  54. {
  55. return buffer;
  56. }
  57. //中断函数
  58. void UARTIsr() interrupt 4
  59. {
  60. if (TI) //TI:串口 1 发送中断请求标志位,停止位被发送出去时置1,向CPU请求中断
  61. {
  62. TI = 0;
  63. busy = 0;
  64. }
  65. if (RI) //RI:串口 1 接收中断请求标志位,接收到停止位时,置1,向CPU请求中断
  66. {
  67. RI = 0;
  68. buffer = SBUF;
  69. UART_RxFlag = 1 ;
  70. //wptr &= 0x0f;
  71. }
  72. }
  1. #ifndef __UART_H__
  2. #define __UART_H__
  3. #include "config.h"
  4. #include <stdio.h>
  5. #include <stdlib.h>
  6. #include <string.h>
  7. #define BRT (65536 - MAIN_Fosc / 9600 / 4) //BRT定时器2的重载值 1T
  8. void UART_Init();
  9. void UART_SendChar(unsigned char dat); //发送一个字符
  10. void UART_SendString(unsigned char *p); //发送字符串
  11. char putchar(char c);
  12. u8 UART_GetRxData(void);
  13. u8 UART_GetRxFlag(void);
  14. #endif
  1. #include <STC8G.h>
  2. #include "intrins.h"
  3. #include "Delay.h"
  4. #include "config.h"
  5. #include "LED.h"
  6. #include "KEY.h"
  7. #include "ADC.h"
  8. #include "UART.h"
  9. u8 RxData;
  10. void main(void)
  11. {
  12. LED_Init();
  13. UART_Init();
  14. while(1)
  15. {
  16. //printf("UART test\r\n");
  17. //UART_SendChar('a');
  18. Delay_ms(1000);
  19. if(UART_GetRxFlag() == 1)
  20. {
  21. RxData=UART_GetRxData();
  22. //UART_SendChar(RxData);
  23. printf("RxDate: %c\n",RxData);
  24. LED_TURN();
  25. }
  26. }
  27. }

数据手册

用到了定时器、中断、串口。