里依赖文件库

老版本(2022.03.01):
STC8G-STC8H-LIB-DEMO-CODE_2022.03.01.zip
新版本(2023.07.17):
STC8G-STC8H-LIB-DEMO-CODE2023.07.17优化版.zip
优化版库函数(2023.10.06):
STC8G-STC8H库函数_优化版2023-10-6.zip :::warning 优化版库函数将NVIC.cNVIC.hSwitch.hType_def.h拷贝到对应外设依赖中,不需要再单独添加这些依赖了 :::

以下模板代码均基于官方2023.07.17版本。

程序结构

  1. #include "Config.h"
  2. #include "GPIO.h"
  3. #include "Delay.h"
  4. int main() {
  5. EAXSFR();
  6. GPIO_config();
  7. EA = 1;
  8. while(1) {
  9. }
  10. }

GPIO操作

初始化所有

  1. P0M1 = 0; P0M0 = 0;
  2. P1M1 = 0; P1M0 = 0;
  3. P2M1 = 0; P2M0 = 0;
  4. P3M1 = 0; P3M0 = 0;
  5. P4M1 = 0; P4M0 = 0;
  6. P5M1 = 0; P5M0 = 0;
  7. P6M1 = 0; P6M0 = 0;
  8. P7M1 = 0; P7M0 = 0;

使用宏配置IO口

  1. #define GPIO_Pin_0 0x01 //IO引脚 Px.0
  2. #define GPIO_Pin_1 0x02 //IO引脚 Px.1
  3. #define GPIO_Pin_2 0x04 //IO引脚 Px.2
  4. #define GPIO_Pin_3 0x08 //IO引脚 Px.3
  5. #define GPIO_Pin_4 0x10 //IO引脚 Px.4
  6. #define GPIO_Pin_5 0x20 //IO引脚 Px.5
  7. #define GPIO_Pin_6 0x40 //IO引脚 Px.6
  8. #define GPIO_Pin_7 0x80 //IO引脚 Px.7
  9. #define GPIO_Pin_LOW 0x0F //IO低4位引脚
  10. #define GPIO_Pin_HIGH 0xF0 //IO高4位引脚
  11. #define GPIO_Pin_All 0xFF //IO所有引脚
  12. //准双向口 P01为例
  13. P0_MODE_IO_PU(GPIO_Pin_1);
  14. //高阻输入 P01为例
  15. P0_MODE_IN_HIZ(GPIO_Pin_1);
  16. //漏极开路 P01为例
  17. P0_MODE_OUT_OD(GPIO_Pin_1);
  18. //推挽输出 P01为例
  19. P0_MODE_OUT_PP(GPIO_Pin_1);

使用函数配置IO口

  1. void GPIO_config(void) {
  2. GPIO_InitTypeDef GPIO_InitStructure; //结构定义
  3. GPIO_InitStructure.Pin = GPIO_Pin_3; //指定要初始化的IO,
  4. GPIO_InitStructure.Mode = GPIO_PullUp; //指定IO的输入或输出方式,GPIO_PullUp,GPIO_HighZ,GPIO_OUT_OD,GPIO_OUT_PP
  5. GPIO_Inilize(GPIO_P5, &GPIO_InitStructure);//初始化
  6. }

UART操作

添加NVIC.c UART.c UART_Isr.c
配置EA = 1

头文件

  1. #include "UART.h"
  2. #include "NVIC.h"
  3. #include "Switch.h"

初始化

  1. void UART_config(void) {
  2. // >>> 记得添加 NVIC.c, UART.c, UART_Isr.c <<<
  3. COMx_InitDefine COMx_InitStructure; //结构定义
  4. COMx_InitStructure.UART_Mode = UART_8bit_BRTx; //模式, UART_ShiftRight,UART_8bit_BRTx,UART_9bit,UART_9bit_BRTx
  5. COMx_InitStructure.UART_BRT_Use = BRT_Timer1; //选择波特率发生器, BRT_Timer1, BRT_Timer2 (注意: 串口2固定使用BRT_Timer2)
  6. COMx_InitStructure.UART_BaudRate = 115200ul; //波特率, 一般 110 ~ 115200
  7. COMx_InitStructure.UART_RxEnable = ENABLE; //接收允许, ENABLE或DISABLE
  8. COMx_InitStructure.BaudRateDouble = DISABLE; //波特率加倍, ENABLE或DISABLE
  9. UART_Configuration(UART1, &COMx_InitStructure); //初始化串口1 UART1,UART2,UART3,UART4
  10. NVIC_UART1_Init(ENABLE,Priority_1); //中断使能, ENABLE/DISABLE; 优先级(低到高) Priority_0,Priority_1,Priority_2,Priority_3
  11. UART1_SW(UART1_SW_P30_P31); // 引脚选择, UART1_SW_P30_P31,UART1_SW_P36_P37,UART1_SW_P16_P17,UART1_SW_P43_P44
  12. }
  1. void UART_config(void) {
  2. COMx_InitDefine COMx_InitStructure; //结构定义
  3. COMx_InitStructure.UART_Mode = UART_8bit_BRTx; //模式, UART_ShiftRight,UART_8bit_BRTx,UART_9bit,UART_9bit_BRTx
  4. COMx_InitStructure.UART_BRT_Use = BRT_Timer2; //选择波特率发生器, BRT_Timer1, BRT_Timer2 (注意: 串口2固定使用BRT_Timer2)
  5. COMx_InitStructure.UART_BaudRate = 115200ul; //波特率, 一般 110 ~ 115200
  6. COMx_InitStructure.UART_RxEnable = ENABLE; //接收允许, ENABLE或DISABLE
  7. COMx_InitStructure.BaudRateDouble = DISABLE; //波特率加倍, ENABLE或DISABLE
  8. UART_Configuration(UART2, &COMx_InitStructure); //初始化串口1 UART1,UART2,UART3,UART4
  9. NVIC_UART2_Init(ENABLE,Priority_1); //中断使能, ENABLE/DISABLE; 优先级(低到高) Priority_0,Priority_1,Priority_2,Priority_3
  10. UART2_SW(UART2_SW_P10_P11); // 引脚选择, UART2_SW_P10_P11,UART2_SW_P46_P47
  11. }
  1. void UART_config(void) {
  2. COMx_InitDefine COMx_InitStructure; //结构定义
  3. COMx_InitStructure.UART_Mode = UART_8bit_BRTx; //模式, UART_ShiftRight,UART_8bit_BRTx,UART_9bit,UART_9bit_BRTx
  4. COMx_InitStructure.UART_BRT_Use = BRT_Timer3; //选择波特率发生器, BRT_Timer1, BRT_Timer2 (注意: 串口2固定使用BRT_Timer2)
  5. COMx_InitStructure.UART_BaudRate = 115200ul; //波特率, 一般 110 ~ 115200
  6. COMx_InitStructure.UART_RxEnable = ENABLE; //接收允许, ENABLE或DISABLE
  7. COMx_InitStructure.BaudRateDouble = DISABLE; //波特率加倍, ENABLE或DISABLE
  8. UART_Configuration(UART3, &COMx_InitStructure); //初始化串口1 UART1,UART2,UART3,UART4
  9. NVIC_UART3_Init(ENABLE,Priority_1); //中断使能, ENABLE/DISABLE; 优先级(低到高) Priority_0,Priority_1,Priority_2,Priority_3
  10. UART3_SW(UART3_SW_P00_P01); // 引脚选择, UART3_SW_P00_P01,UART3_SW_P50_P51
  11. }
  1. void UART_config(void) {
  2. COMx_InitDefine COMx_InitStructure; //结构定义
  3. COMx_InitStructure.UART_Mode = UART_8bit_BRTx; //模式, UART_ShiftRight,UART_8bit_BRTx,UART_9bit,UART_9bit_BRTx
  4. COMx_InitStructure.UART_BRT_Use = BRT_Timer4; //选择波特率发生器, BRT_Timer1, BRT_Timer2 (注意: 串口2固定使用BRT_Timer2)
  5. COMx_InitStructure.UART_BaudRate = 115200ul; //波特率, 一般 110 ~ 115200
  6. COMx_InitStructure.UART_RxEnable = ENABLE; //接收允许, ENABLE或DISABLE
  7. COMx_InitStructure.BaudRateDouble = DISABLE; //波特率加倍, ENABLE或DISABLE
  8. UART_Configuration(UART4, &COMx_InitStructure); //初始化串口1 UART1,UART2,UART3,UART4
  9. NVIC_UART4_Init(ENABLE,Priority_1); //中断使能, ENABLE/DISABLE; 优先级(低到高) Priority_0,Priority_1,Priority_2,Priority_3
  10. UART4_SW(UART4_SW_P02_P03); // 引脚选择, UART4_SW_P02_P03,UART4_SW_P52_P53
  11. }
  • UART_BaudRate:波特率
  • UARTx_SW: 引脚
  • UART_BRT_Use: 发生器
  • UART_Configuration中的UART1

    接收逻辑

    1. if(COM1.RX_TimeOut > 0) {
    2. //超时计数
    3. if(--COM1.RX_TimeOut == 0) {
    4. if(COM1.RX_Cnt > 0) {
    5. for(i=0; i<COM1.RX_Cnt; i++) {
    6. // RX1_Buffer[i]存的是接收的数据,写出用 TX1_write2buff
    7. // TODO: 做具体的逻辑 on_uart1_recv
    8. }
    9. }
    10. COM1.RX_Cnt = 0;
    11. }
    12. }
    1. if(COM2.RX_TimeOut > 0) {
    2. //超时计数
    3. if(--COM2.RX_TimeOut == 0) {
    4. if(COM2.RX_Cnt > 0) {
    5. for(i=0; i<COM2.RX_Cnt; i++) {
    6. // RX2_Buffer[i]存的是接收的数据,写出用 TX2_write2buff
    7. // TODO: 做具体的逻辑 on_uart2_recv
    8. }
    9. }
    10. COM2.RX_Cnt = 0;
    11. }
    12. }
    1. if(COM3.RX_TimeOut > 0) {
    2. //超时计数
    3. if(--COM3.RX_TimeOut == 0) {
    4. if(COM3.RX_Cnt > 0) {
    5. for(i=0; i<COM3.RX_Cnt; i++) {
    6. // TODO: RX3_Buffer[i]存的是接收的数据
    7. // TODO: 做具体的逻辑 on_uart3_recv
    8. }
    9. }
    10. COM3.RX_Cnt = 0;
    11. }
    12. }
    1. if(COM4.RX_TimeOut > 0) {
    2. //超时计数
    3. if(--COM4.RX_TimeOut == 0) {
    4. if(COM4.RX_Cnt > 0) {
    5. for(i=0; i<COM4.RX_Cnt; i++) {
    6. // TODO: RX4_Buffer[i]存的是接收的数据
    7. // TODO: 做具体的逻辑 on_uart4_recv
    8. }
    9. }
    10. COM4.RX_Cnt = 0;
    11. }
    12. }

    发送

    1. TX1_write2buff(xx);// 写一个byte
    2. PrintString1(""); // 写字符串
    1. TX2_write2buff(xx);// 写一个byte
    2. PrintString2(""); // 写字符串
    1. TX3_write2buff(xx);// 写一个byte
    2. PrintString3(""); // 写字符串
    1. TX4_write2buff(xx);// 写一个byte
    2. PrintString4(""); // 写字符串

    配置printf

    保留用到的UART宏
    1. #define UART1 1 //使用哪些串口就开对应的定义,不用的串口可屏蔽掉定义,节省资源
    2. //#define UART2 2
    3. //#define UART3 3
    4. //#define UART4 4
    指定printf函数使用UART1串口
    1. #define PRINTF_SELECT UART1 //选择 printf 函数所使用的串口,参数 UART1~UART4

    Timer操作

    导入依赖

  1. Timer.c``Timer.h``Timer_Isr.c
  2. NVIC.c``NVIC.h
    1. #include "Timer.h"
    2. #include "NVIC.h"

    初始化

    1. void Timer_config(void)
    2. {
    3. TIM_InitTypeDef TIM_InitStructure; //结构定义
    4. //定时器0做16位自动重装, 中断频率为1000HZ
    5. TIM_InitStructure.TIM_Mode = TIM_16BitAutoReload; //指定工作模式, TIM_16BitAutoReload,TIM_16Bit,TIM_8BitAutoReload,TIM_16BitAutoReloadNoMask
    6. TIM_InitStructure.TIM_ClkSource = TIM_CLOCK_1T; //指定时钟源, TIM_CLOCK_1T,TIM_CLOCK_12T,TIM_CLOCK_Ext
    7. TIM_InitStructure.TIM_ClkOut = DISABLE; //是否输出高速脉冲, ENABLE或DISABLE
    8. TIM_InitStructure.TIM_Value = 65536UL - (MAIN_Fosc / 1000UL); //初值,
    9. TIM_InitStructure.TIM_Run = ENABLE; //是否初始化后启动定时器, ENABLE或DISABLE
    10. Timer_Inilize(Timer0,&TIM_InitStructure); //初始化Timer0 Timer0,Timer1,Timer2,Timer3,Timer4
    11. NVIC_Timer0_Init(ENABLE,Priority_0); //中断使能, ENABLE/DISABLE; 优先级(低到高) Priority_0,Priority_1,Priority_2,Priority_3
    12. }
    1. void Timer_config(void)
    2. {
    3. TIM_InitTypeDef TIM_InitStructure; //结构定义
    4. //定时器1做16位自动重装, 中断频率为1000HZ
    5. TIM_InitStructure.TIM_Mode = TIM_16BitAutoReload; //指定工作模式, TIM_16BitAutoReload,TIM_16Bit,TIM_8BitAutoReload,TIM_T1Stop
    6. TIM_InitStructure.TIM_ClkSource = TIM_CLOCK_1T; //指定时钟源, TIM_CLOCK_1T,TIM_CLOCK_12T,TIM_CLOCK_Ext
    7. TIM_InitStructure.TIM_ClkOut = DISABLE; //是否输出高速脉冲, ENABLE或DISABLE
    8. TIM_InitStructure.TIM_Value = 65536UL - (MAIN_Fosc / 1000); //初值,
    9. TIM_InitStructure.TIM_Run = ENABLE; //是否初始化后启动定时器, ENABLE或DISABLE
    10. Timer_Inilize(Timer1,&TIM_InitStructure); //初始化Timer1 Timer0,Timer1,Timer2,Timer3,Timer4
    11. NVIC_Timer1_Init(ENABLE,Priority_0); //中断使能, ENABLE/DISABLE; 优先级(低到高) Priority_0,Priority_1,Priority_2,Priority_3
    12. }
    1. void Timer_config(void)
    2. {
    3. TIM_InitTypeDef TIM_InitStructure; //结构定义
    4. //定时器2做16位自动重装, 中断频率为1000HZ
    5. TIM_InitStructure.TIM_ClkSource = TIM_CLOCK_1T; //指定时钟源, TIM_CLOCK_1T,TIM_CLOCK_12T,TIM_CLOCK_Ext
    6. TIM_InitStructure.TIM_ClkOut = DISABLE; //是否输出高速脉冲, ENABLE或DISABLE
    7. TIM_InitStructure.TIM_Value = 65536UL - (MAIN_Fosc / 1000); //初值
    8. TIM_InitStructure.TIM_PS = 0; //8位预分频器(n+1), 0~255, (注意:并非所有系列都有此寄存器,详情请查看数据手册)
    9. TIM_InitStructure.TIM_Run = ENABLE; //是否初始化后启动定时器, ENABLE或DISABLE
    10. Timer_Inilize(Timer2,&TIM_InitStructure); //初始化Timer2 Timer0,Timer1,Timer2,Timer3,Timer4
    11. NVIC_Timer2_Init(ENABLE,NULL); //中断使能, ENABLE/DISABLE; 无优先级
    12. }
    1. void Timer_config(void)
    2. {
    3. TIM_InitTypeDef TIM_InitStructure; //结构定义
    4. //定时器3做16位自动重装, 中断频率为100HZ
    5. TIM_InitStructure.TIM_ClkSource = TIM_CLOCK_12T; //指定时钟源, TIM_CLOCK_1T,TIM_CLOCK_12T,TIM_CLOCK_Ext
    6. TIM_InitStructure.TIM_ClkOut = DISABLE; //是否输出高速脉冲, ENABLE或DISABLE
    7. TIM_InitStructure.TIM_Value = 65536UL - (MAIN_Fosc / (100*12)); //初值
    8. TIM_InitStructure.TIM_PS = 0; //8位预分频器(n+1), 0~255, (注意:并非所有系列都有此寄存器,详情请查看数据手册)
    9. TIM_InitStructure.TIM_Run = ENABLE; //是否初始化后启动定时器, ENABLE或DISABLE
    10. Timer_Inilize(Timer3,&TIM_InitStructure); //初始化Timer3 Timer0,Timer1,Timer2,Timer3,Timer4
    11. NVIC_Timer3_Init(ENABLE,NULL); //中断使能, ENABLE/DISABLE; 无优先级
    12. }
    1. void Timer_config(void)
    2. {
    3. TIM_InitTypeDef TIM_InitStructure; //结构定义
    4. //定时器4做16位自动重装, 中断频率为50HZ
    5. TIM_InitStructure.TIM_ClkSource = TIM_CLOCK_12T; //指定时钟源, TIM_CLOCK_1T,TIM_CLOCK_12T,TIM_CLOCK_Ext
    6. TIM_InitStructure.TIM_ClkOut = DISABLE; //是否输出高速脉冲, ENABLE或DISABLE
    7. TIM_InitStructure.TIM_Value = 65536UL - (MAIN_Fosc / (50*12)); //初值
    8. TIM_InitStructure.TIM_PS = 0; //8位预分频器(n+1), 0~255, (注意:并非所有系列都有此寄存器,详情请查看数据手册)
    9. TIM_InitStructure.TIM_Run = ENABLE; //是否初始化后启动定时器, ENABLE或DISABLE
    10. Timer_Inilize(Timer4,&TIM_InitStructure); //初始化Timer4 Timer0,Timer1,Timer2,Timer3,Timer4
    11. NVIC_Timer4_Init(ENABLE,NULL); //中断使能, ENABLE/DISABLE; 无优先级
    12. }

实现中断函数

以Timer0为例:
方式1:
修改Timer_Isr.c实现中断函数的调用,并在main.c中声明实现timer0_call函数

  1. extern void timer0_call();
  2. //========================================================================
  3. // 函数: Timer0_ISR_Handler
  4. // 描述: Timer0中断函数.
  5. // 参数: none.
  6. // 返回: none.
  7. // 版本: V1.0, 2020-09-23
  8. //========================================================================
  9. void Timer0_ISR_Handler (void) interrupt TMR0_VECTOR //进中断时已经清除标志
  10. {
  11. // TODO: 在此处添加用户代码
  12. timer0_call();
  13. }

然后在main.c中实现timer0_call:

  1. void timer0_call(){
  2. // TODO: 在此处添加用户代码
  3. }

方式2:
直接在main.c中实现interrupt函数(记得删掉或注释掉Timer_Isr.c中对应的中断函数)

  1. void Timer0_ISR (void) interrupt TMR0_VECTOR //进中断时已经清除标志
  2. {
  3. // TODO: 在此处添加用户代码
  4. }

PWM操作

依赖及头文件

  1. #include "STC8H_PWM.h"
  2. #include "NVIC.h"
  3. #include "Switch.h"

扩展寄存器访问使能

  1. EAXSFR(); /* 扩展寄存器访问使能 */

初始化PWMA

  1. #define PERIOD (MAIN_Fosc / 1000)
  2. PWMx_Duty dutyA;
  3. void PWM_config(void)
  4. {
  5. PWMx_InitDefine PWMx_InitStructure;
  6. // 配置PWM1
  7. PWMx_InitStructure.PWM_Mode = CCMRn_PWM_MODE1; //模式, CCMRn_FREEZE,CCMRn_MATCH_VALID,CCMRn_MATCH_INVALID,CCMRn_ROLLOVER,CCMRn_FORCE_INVALID,CCMRn_FORCE_VALID,CCMRn_PWM_MODE1,CCMRn_PWM_MODE2
  8. PWMx_InitStructure.PWM_Duty = dutyA.PWM1_Duty; //PWM占空比时间, 0~Period
  9. PWMx_InitStructure.PWM_EnoSelect = ENO1P | ENO1N; //输出通道选择, ENO1P,ENO1N,ENO2P,ENO2N,ENO3P,ENO3N,ENO4P,ENO4N / ENO5P,ENO6P,ENO7P,ENO8P
  10. PWM_Configuration(PWM1, &PWMx_InitStructure); //初始化PWM
  11. // 配置PWM2
  12. PWMx_InitStructure.PWM_Mode = CCMRn_PWM_MODE1; //模式, CCMRn_FREEZE,CCMRn_MATCH_VALID,CCMRn_MATCH_INVALID,CCMRn_ROLLOVER,CCMRn_FORCE_INVALID,CCMRn_FORCE_VALID,CCMRn_PWM_MODE1,CCMRn_PWM_MODE2
  13. PWMx_InitStructure.PWM_Duty = dutyA.PWM2_Duty; //PWM占空比时间, 0~Period
  14. PWMx_InitStructure.PWM_EnoSelect = ENO2P | ENO2N; //输出通道选择, ENO1P,ENO1N,ENO2P,ENO2N,ENO3P,ENO3N,ENO4P,ENO4N / ENO5P,ENO6P,ENO7P,ENO8P
  15. PWM_Configuration(PWM2, &PWMx_InitStructure); //初始化PWM
  16. // 配置PWM3
  17. PWMx_InitStructure.PWM_Mode = CCMRn_PWM_MODE1; //模式, CCMRn_FREEZE,CCMRn_MATCH_VALID,CCMRn_MATCH_INVALID,CCMRn_ROLLOVER,CCMRn_FORCE_INVALID,CCMRn_FORCE_VALID,CCMRn_PWM_MODE1,CCMRn_PWM_MODE2
  18. PWMx_InitStructure.PWM_Duty = dutyA.PWM3_Duty; //PWM占空比时间, 0~Period
  19. PWMx_InitStructure.PWM_EnoSelect = ENO3P | ENO3N; //输出通道选择, ENO1P,ENO1N,ENO2P,ENO2N,ENO3P,ENO3N,ENO4P,ENO4N / ENO5P,ENO6P,ENO7P,ENO8P
  20. PWM_Configuration(PWM3, &PWMx_InitStructure);
  21. // 配置PWM4
  22. PWMx_InitStructure.PWM_Mode = CCMRn_PWM_MODE1; //模式, CCMRn_FREEZE,CCMRn_MATCH_VALID,CCMRn_MATCH_INVALID,CCMRn_ROLLOVER,CCMRn_FORCE_INVALID,CCMRn_FORCE_VALID,CCMRn_PWM_MODE1,CCMRn_PWM_MODE2
  23. PWMx_InitStructure.PWM_Duty = dutyA.PWM4_Duty; //PWM占空比时间, 0~Period
  24. PWMx_InitStructure.PWM_EnoSelect = ENO4P | ENO4N; //输出通道选择, ENO1P,ENO1N,ENO2P,ENO2N,ENO3P,ENO3N,ENO4P,ENO4N / ENO5P,ENO6P,ENO7P,ENO8P
  25. PWM_Configuration(PWM4, &PWMx_InitStructure);
  26. // 配置PWMA
  27. PWMx_InitStructure.PWM_Period = PERIOD - 1; //周期时间, 0~65535
  28. PWMx_InitStructure.PWM_DeadTime = 0; //死区发生器设置, 0~255
  29. PWMx_InitStructure.PWM_MainOutEnable= ENABLE; //主输出使能, ENABLE,DISABLE
  30. PWMx_InitStructure.PWM_CEN_Enable = ENABLE; //使能计数器, ENABLE,DISABLE
  31. PWM_Configuration(PWMA, &PWMx_InitStructure); //初始化PWM通用寄存器, PWMA,PWMB
  32. // 切换PWM通道
  33. PWM1_SW(PWM1_SW_P10_P11); //PWM1_SW_P10_P11,PWM1_SW_P20_P21,PWM1_SW_P60_P61
  34. PWM2_SW(PWM2_SW_P12_P13); //PWM2_SW_P12_P13,PWM2_SW_P22_P23,PWM2_SW_P62_P63
  35. PWM3_SW(PWM3_SW_P14_P15); //PWM3_SW_P14_P15,PWM3_SW_P24_P25,PWM3_SW_P64_P65
  36. PWM4_SW(PWM4_SW_P16_P17); //PWM4_SW_P16_P17,PWM4_SW_P26_P27,PWM4_SW_P66_P67,PWM4_SW_P34_P33
  37. // 初始化PWMA的中断
  38. NVIC_PWM_Init(PWMA,DISABLE,Priority_0);
  39. }
  • 总配置中的 PWM_Period, 配置周期计数。#define PERIOD (MAIN_Fosc / 1000) 1000 表示1s执行1000次。此处为计数值。
  • PWM1_Duty表示占空比,1个周期中高电平或者低电平出现的百分比,此处为百分比的计数值。

    初始化PWMB

    1. #define PERIOD (MAIN_Fosc / 1000)
    2. PWMx_Duty dutyB;
    3. void PWM_config(void)
    4. {
    5. PWMx_InitDefine PWMx_InitStructure;
    6. // 配置PWM5
    7. PWMx_InitStructure.PWM_Mode = CCMRn_PWM_MODE1; //模式, CCMRn_FREEZE,CCMRn_MATCH_VALID,CCMRn_MATCH_INVALID,CCMRn_ROLLOVER,CCMRn_FORCE_INVALID,CCMRn_FORCE_VALID,CCMRn_PWM_MODE1,CCMRn_PWM_MODE2
    8. PWMx_InitStructure.PWM_Duty = dutyB.PWM5_Duty; //PWM占空比时间, 0~Period
    9. PWMx_InitStructure.PWM_EnoSelect = ENO5P; //输出通道选择, ENO1P,ENO1N,ENO2P,ENO2N,ENO3P,ENO3N,ENO4P,ENO4N / ENO5P,ENO6P,ENO7P,ENO8P
    10. PWM_Configuration(PWM5, &PWMx_InitStructure); //初始化PWM, PWMA,PWMB
    11. // 配置PWM6
    12. PWMx_InitStructure.PWM_Mode = CCMRn_PWM_MODE1; //模式, CCMRn_FREEZE,CCMRn_MATCH_VALID,CCMRn_MATCH_INVALID,CCMRn_ROLLOVER,CCMRn_FORCE_INVALID,CCMRn_FORCE_VALID,CCMRn_PWM_MODE1,CCMRn_PWM_MODE2
    13. PWMx_InitStructure.PWM_Duty = dutyB.PWM6_Duty; //PWM占空比时间, 0~Period
    14. PWMx_InitStructure.PWM_EnoSelect = ENO6P; //输出通道选择, ENO1P,ENO1N,ENO2P,ENO2N,ENO3P,ENO3N,ENO4P,ENO4N / ENO5P,ENO6P,ENO7P,ENO8P
    15. PWM_Configuration(PWM6, &PWMx_InitStructure); //初始化PWM, PWMA,PWMB
    16. // 配置PWM7
    17. PWMx_InitStructure.PWM_Mode = CCMRn_PWM_MODE1; //模式, CCMRn_FREEZE,CCMRn_MATCH_VALID,CCMRn_MATCH_INVALID,CCMRn_ROLLOVER,CCMRn_FORCE_INVALID,CCMRn_FORCE_VALID,CCMRn_PWM_MODE1,CCMRn_PWM_MODE2
    18. PWMx_InitStructure.PWM_Duty = dutyB.PWM7_Duty; //PWM占空比时间, 0~Period
    19. PWMx_InitStructure.PWM_EnoSelect = ENO7P; //输出通道选择, ENO1P,ENO1N,ENO2P,ENO2N,ENO3P,ENO3N,ENO4P,ENO4N / ENO5P,ENO6P,ENO7P,ENO8P
    20. PWM_Configuration(PWM7, &PWMx_InitStructure); //初始化PWM, PWMA,PWMB
    21. // 配置PWM8
    22. PWMx_InitStructure.PWM_Mode = CCMRn_PWM_MODE1; //模式, CCMRn_FREEZE,CCMRn_MATCH_VALID,CCMRn_MATCH_INVALID,CCMRn_ROLLOVER,CCMRn_FORCE_INVALID,CCMRn_FORCE_VALID,CCMRn_PWM_MODE1,CCMRn_PWM_MODE2
    23. PWMx_InitStructure.PWM_Duty = dutyB.PWM8_Duty; //PWM占空比时间, 0~Period
    24. PWMx_InitStructure.PWM_EnoSelect = ENO8P; //输出通道选择, ENO1P,ENO1N,ENO2P,ENO2N,ENO3P,ENO3N,ENO4P,ENO4N / ENO5P,ENO6P,ENO7P,ENO8P
    25. PWM_Configuration(PWM8, &PWMx_InitStructure); //初始化PWM, PWMA,PWMB
    26. // 配置PWMB
    27. PWMx_InitStructure.PWM_Period = PERIOD - 1; //周期时间, 0~65535
    28. PWMx_InitStructure.PWM_DeadTime = 0; //死区发生器设置, 0~255
    29. PWMx_InitStructure.PWM_MainOutEnable= ENABLE; //主输出使能, ENABLE,DISABLE
    30. PWMx_InitStructure.PWM_CEN_Enable = ENABLE; //使能计数器, ENABLE,DISABLE
    31. PWM_Configuration(PWMB, &PWMx_InitStructure); //初始化PWM通用寄存器, PWMA,PWMB
    32. // 切换PWM通道
    33. PWM5_SW(PWM5_SW_P20); //PWM5_SW_P20,PWM5_SW_P17,PWM5_SW_P00,PWM5_SW_P74
    34. PWM6_SW(PWM6_SW_P21); //PWM6_SW_P21,PWM6_SW_P54,PWM6_SW_P01,PWM6_SW_P75
    35. PWM7_SW(PWM7_SW_P22); //PWM7_SW_P22,PWM7_SW_P33,PWM7_SW_P02,PWM7_SW_P76
    36. PWM8_SW(PWM8_SW_P23); //PWM8_SW_P23,PWM8_SW_P34,PWM8_SW_P03,PWM8_SW_P77
    37. // 初始化PWMB的中断
    38. NVIC_PWM_Init(PWMB,DISABLE,Priority_0);
    39. }

ADC操作

初始化

  1. /******************* AD配置函数 *******************/
  2. void ADC_config(void)
  3. {
  4. ADC_InitTypeDef ADC_InitStructure; //结构定义
  5. ADC_InitStructure.ADC_SMPduty = 31; //ADC 模拟信号采样时间控制, 0~31(注意: SMPDUTY 一定不能设置小于 10)
  6. ADC_InitStructure.ADC_CsSetup = 0; //ADC 通道选择时间控制 0(默认),1
  7. ADC_InitStructure.ADC_CsHold = 1; //ADC 通道选择保持时间控制 0,1(默认),2,3
  8. ADC_InitStructure.ADC_Speed = ADC_SPEED_2X1T; //设置 ADC 工作时钟频率 ADC_SPEED_2X1T~ADC_SPEED_2X16T
  9. ADC_InitStructure.ADC_AdjResult = ADC_RIGHT_JUSTIFIED; //ADC结果调整, ADC_LEFT_JUSTIFIED,ADC_RIGHT_JUSTIFIED
  10. ADC_Inilize(&ADC_InitStructure); //初始化
  11. ADC_PowerControl(ENABLE); //ADC电源开关, ENABLE或DISABLE
  12. NVIC_ADC_Init(DISABLE,Priority_0); //中断使能, ENABLE/DISABLE; 优先级(低到高) Priority_0,Priority_1,Priority_2,Priority_3
  13. }

获取值

  1. u16 result = Get_ADCResult(chn); // chn: ADC_CH0, ADC_CH1, ADC_CH2 .... ADC_CH15

计算电压

  1. float v = result * 基准电压 / 采样精度;
  • 2.5为参考电压值,是实际情况而定
  • 基准电压:根据电路情况确定,基准电压芯片默认2.5V
  • 采样精度: 12位adc

模板代码📝 - 图1

I2C操作

初始化

拷贝如下文件:

  1. I2C.c I2C.h
  2. NVIC.c NVIC.h
  3. Switch.h

    1. void GPIO_config(void) {
    2. GPIO_InitTypeDef GPIO_InitStructure; //结构定义
    3. GPIO_InitStructure.Pin = GPIO_Pin_2 | GPIO_Pin_3; //指定要初始化的IO,
    4. GPIO_InitStructure.Mode = GPIO_OUT_OD; //指定IO的输入或输出方式,GPIO_PullUp,GPIO_HighZ,GPIO_OUT_OD,GPIO_OUT_PP
    5. GPIO_Inilize(GPIO_P3, &GPIO_InitStructure);//初始化
    6. }
    1. /**************** I2C初始化函数 *****************/
    2. void I2C_config(void)
    3. {
    4. I2C_InitTypeDef I2C_InitStructure;
    5. I2C_InitStructure.I2C_Mode = I2C_Mode_Master; //主从选择 I2C_Mode_Master, I2C_Mode_Slave
    6. I2C_InitStructure.I2C_Enable = ENABLE; //I2C功能使能, ENABLE, DISABLE
    7. I2C_InitStructure.I2C_MS_WDTA = DISABLE; //主机使能自动发送, ENABLE, DISABLE
    8. I2C_InitStructure.I2C_Speed = 13; //总线速度=Fosc/2/(Speed*2+4), 0~63
    9. // 400k, 24M => 13
    10. I2C_Init(&I2C_InitStructure);
    11. NVIC_I2C_Init(I2C_Mode_Master,DISABLE,Priority_0); //主从模式, I2C_Mode_Master, I2C_Mode_Slave; 中断使能, ENABLE/DISABLE; 优先级(低到高) Priority_0,Priority_1,Priority_2,Priority_3
    12. I2C_SW(I2C_P33_P32); //I2C_P14_P15,I2C_P24_P25,I2C_P33_P32
    13. }

    INT中断

    外部中断编写

  4. 引入外部中断库函数

    1. Exti.h``Exti.c``**Exti_Isr.c**
    2. NVIC.h NVIC.c
  5. 配置外部中断 ```c

    include “Exti.h”

    include “NVIC.h”

/** INT配置 **/ void Exti_config(void) { EXTI_InitTypeDef Exti_InitStructure; //结构定义

  1. Exti_InitStructure.EXTI_Mode = EXT_MODE_RiseFall;//中断模式, EXT_MODE_RiseFall,EXT_MODE_Fall
  2. Ext_Inilize(EXT_INT0,&Exti_InitStructure); //初始化
  3. NVIC_INT0_Init(ENABLE,Priority_0); //中断使能, ENABLE/DISABLE; 优先级(低到高) Priority_0,Priority_1,Priority_2,Priority_3

} void ext_int0_call(void) { // 当中断触发时的实现逻辑 }

  1. 3. 调用中断触发函数
  2. ```c
  3. extern void ext_int0_call();
  4. //========================================================================
  5. // 函数: INT0_ISR_Handler
  6. // 描述: INT0中断函数.
  7. // 参数: none.
  8. // 返回: none.
  9. // 版本: V1.0, 2020-09-23
  10. //========================================================================
  11. void INT0_ISR_Handler (void) interrupt INT0_VECTOR //进中断时已经清除标志
  12. {
  13. ext_int0_call();
  14. }
外部中断 引脚 备注
INT0 P3.2 支持上升沿和下降沿中断
INT1 P3.3 支持上升沿和下降沿中断
INT2 P3.6 只支持下降沿中断
INT3 P3.7 只支持下降沿中断
INT4 P3.0 只支持下降沿中断