目录
STC8依赖文件库
程序结构
GPIO操作
初始化所有
使用宏配置IO口
使用函数配置IO口
UART操作
头文件
初始化
UART1
UART2
UART3
UART4
接收逻辑
UART1
UART2
UART3
UART4
发送
UART1
UART2
UART3
UART4
配置printf
Timer操作
导入依赖
初始化
Timer0
Timer1
Timer2
Timer3
Timer4
实现中断函数
PWM操作
依赖及头文件
扩展寄存器访问使能
初始化PWMA
初始化PWMB
ADC操作
初始化
获取值
计算电压
I2C操作
初始化
GPIO初始化
I2C初始化
INT中断
外部中断编写
1. 引入外部中断库函数
2.配置外部中断
3.调用中断触发函数
STC8依赖文件库
老版本(2022.03.01):
📎STC8G-STC8H-LIB-DEMO-CODE_2022.03.01.zip
新版本(2023.07.17):
📎STC8G-STC8H-LIB-DEMO-CODE_2023.07.17_优化版.zip
优化版库函数(2023.10.06):
📎STC8G-STC8H库函数_优化版2023-10-6.zip
优化版库函数将
NVIC.c
、NVIC.h
、Switch.h
、Type_def.h
拷贝到对应外设依赖中,不需要再单独添加这些依赖了
以下模板代码均基于官方2023.07.17版本。
程序结构
#include "Config.h"
#include "GPIO.h"
#include "Delay.h"int main() {EAXSFR();GPIO_config();EA = 1;while(1) {}
}
GPIO操作
初始化所有
P0M1 = 0; P0M0 = 0;
P1M1 = 0; P1M0 = 0;
P2M1 = 0; P2M0 = 0;
P3M1 = 0; P3M0 = 0;
P4M1 = 0; P4M0 = 0;
P5M1 = 0; P5M0 = 0;
P6M1 = 0; P6M0 = 0;
P7M1 = 0; P7M0 = 0;
使用宏配置IO口
#define GPIO_Pin_0 0x01 //IO引脚 Px.0
#define GPIO_Pin_1 0x02 //IO引脚 Px.1
#define GPIO_Pin_2 0x04 //IO引脚 Px.2
#define GPIO_Pin_3 0x08 //IO引脚 Px.3
#define GPIO_Pin_4 0x10 //IO引脚 Px.4
#define GPIO_Pin_5 0x20 //IO引脚 Px.5
#define GPIO_Pin_6 0x40 //IO引脚 Px.6
#define GPIO_Pin_7 0x80 //IO引脚 Px.7
#define GPIO_Pin_LOW 0x0F //IO低4位引脚
#define GPIO_Pin_HIGH 0xF0 //IO高4位引脚
#define GPIO_Pin_All 0xFF //IO所有引脚//准双向口 P01为例
P0_MODE_IO_PU(GPIO_Pin_1);
//高阻输入 P01为例
P0_MODE_IN_HIZ(GPIO_Pin_1);
//漏极开路 P01为例
P0_MODE_OUT_OD(GPIO_Pin_1);
//推挽输出 P01为例
P0_MODE_OUT_PP(GPIO_Pin_1);
使用函数配置IO口
void GPIO_config(void) {GPIO_InitTypeDef GPIO_InitStructure; //结构定义GPIO_InitStructure.Pin = GPIO_Pin_3; //指定要初始化的IO,GPIO_InitStructure.Mode = GPIO_PullUp; //指定IO的输入或输出方式,GPIO_PullUp,GPIO_HighZ,GPIO_OUT_OD,GPIO_OUT_PPGPIO_Inilize(GPIO_P5, &GPIO_InitStructure);//初始化
}
UART操作
添加
NVIC.c
UART.c
UART_Isr.c
配置EA = 1
头文件
#include "UART.h"
#include "NVIC.h"
#include "Switch.h"
初始化
UART1
void UART_config(void) {// >>> 记得添加 NVIC.c, UART.c, UART_Isr.c <<<COMx_InitDefine COMx_InitStructure; //结构定义COMx_InitStructure.UART_Mode = UART_8bit_BRTx; //模式, UART_ShiftRight,UART_8bit_BRTx,UART_9bit,UART_9bit_BRTxCOMx_InitStructure.UART_BRT_Use = BRT_Timer1; //选择波特率发生器, BRT_Timer1, BRT_Timer2 (注意: 串口2固定使用BRT_Timer2)COMx_InitStructure.UART_BaudRate = 115200ul; //波特率, 一般 110 ~ 115200COMx_InitStructure.UART_RxEnable = ENABLE; //接收允许, ENABLE或DISABLECOMx_InitStructure.BaudRateDouble = DISABLE; //波特率加倍, ENABLE或DISABLEUART_Configuration(UART1, &COMx_InitStructure); //初始化串口1 UART1,UART2,UART3,UART4NVIC_UART1_Init(ENABLE,Priority_1); //中断使能, ENABLE/DISABLE; 优先级(低到高) Priority_0,Priority_1,Priority_2,Priority_3UART1_SW(UART1_SW_P30_P31); // 引脚选择, UART1_SW_P30_P31,UART1_SW_P36_P37,UART1_SW_P16_P17,UART1_SW_P43_P44
}
UART2
void UART_config(void) {COMx_InitDefine COMx_InitStructure; //结构定义COMx_InitStructure.UART_Mode = UART_8bit_BRTx; //模式, UART_ShiftRight,UART_8bit_BRTx,UART_9bit,UART_9bit_BRTxCOMx_InitStructure.UART_BRT_Use = BRT_Timer2; //选择波特率发生器, BRT_Timer1, BRT_Timer2 (注意: 串口2固定使用BRT_Timer2)COMx_InitStructure.UART_BaudRate = 115200ul; //波特率, 一般 110 ~ 115200COMx_InitStructure.UART_RxEnable = ENABLE; //接收允许, ENABLE或DISABLECOMx_InitStructure.BaudRateDouble = DISABLE; //波特率加倍, ENABLE或DISABLEUART_Configuration(UART2, &COMx_InitStructure); //初始化串口1 UART1,UART2,UART3,UART4NVIC_UART2_Init(ENABLE,Priority_1); //中断使能, ENABLE/DISABLE; 优先级(低到高) Priority_0,Priority_1,Priority_2,Priority_3UART2_SW(UART2_SW_P10_P11); // 引脚选择, UART2_SW_P10_P11,UART2_SW_P46_P47
}
UART3
void UART_config(void) {COMx_InitDefine COMx_InitStructure; //结构定义COMx_InitStructure.UART_Mode = UART_8bit_BRTx; //模式, UART_ShiftRight,UART_8bit_BRTx,UART_9bit,UART_9bit_BRTxCOMx_InitStructure.UART_BRT_Use = BRT_Timer3; //选择波特率发生器, BRT_Timer1, BRT_Timer2 (注意: 串口2固定使用BRT_Timer2)COMx_InitStructure.UART_BaudRate = 115200ul; //波特率, 一般 110 ~ 115200COMx_InitStructure.UART_RxEnable = ENABLE; //接收允许, ENABLE或DISABLECOMx_InitStructure.BaudRateDouble = DISABLE; //波特率加倍, ENABLE或DISABLEUART_Configuration(UART3, &COMx_InitStructure); //初始化串口1 UART1,UART2,UART3,UART4NVIC_UART3_Init(ENABLE,Priority_1); //中断使能, ENABLE/DISABLE; 优先级(低到高) Priority_0,Priority_1,Priority_2,Priority_3UART3_SW(UART3_SW_P00_P01); // 引脚选择, UART3_SW_P00_P01,UART3_SW_P50_P51
}
UART4
void UART_config(void) {COMx_InitDefine COMx_InitStructure; //结构定义COMx_InitStructure.UART_Mode = UART_8bit_BRTx; //模式, UART_ShiftRight,UART_8bit_BRTx,UART_9bit,UART_9bit_BRTxCOMx_InitStructure.UART_BRT_Use = BRT_Timer4; //选择波特率发生器, BRT_Timer1, BRT_Timer2 (注意: 串口2固定使用BRT_Timer2)COMx_InitStructure.UART_BaudRate = 115200ul; //波特率, 一般 110 ~ 115200COMx_InitStructure.UART_RxEnable = ENABLE; //接收允许, ENABLE或DISABLECOMx_InitStructure.BaudRateDouble = DISABLE; //波特率加倍, ENABLE或DISABLEUART_Configuration(UART4, &COMx_InitStructure); //初始化串口1 UART1,UART2,UART3,UART4NVIC_UART4_Init(ENABLE,Priority_1); //中断使能, ENABLE/DISABLE; 优先级(低到高) Priority_0,Priority_1,Priority_2,Priority_3UART4_SW(UART4_SW_P02_P03); // 引脚选择, UART4_SW_P02_P03,UART4_SW_P52_P53
}
- UART_BaudRate:波特率
- UARTx_SW: 引脚
- UART_BRT_Use: 发生器
- UART_Configuration中的UART1
接收逻辑
UART1
if(COM1.RX_TimeOut > 0) {//超时计数if(--COM1.RX_TimeOut == 0) {if(COM1.RX_Cnt > 0) {for(i=0; i<COM1.RX_Cnt; i++) {// RX1_Buffer[i]存的是接收的数据,写出用 TX1_write2buff// TODO: 做具体的逻辑 on_uart1_recv}}COM1.RX_Cnt = 0;}
}
UART2
if(COM2.RX_TimeOut > 0) {//超时计数if(--COM2.RX_TimeOut == 0) {if(COM2.RX_Cnt > 0) {for(i=0; i<COM2.RX_Cnt; i++) {// RX2_Buffer[i]存的是接收的数据,写出用 TX2_write2buff// TODO: 做具体的逻辑 on_uart2_recv}}COM2.RX_Cnt = 0;}
}
UART3
if(COM3.RX_TimeOut > 0) {//超时计数if(--COM3.RX_TimeOut == 0) {if(COM3.RX_Cnt > 0) {for(i=0; i<COM3.RX_Cnt; i++) {// TODO: RX3_Buffer[i]存的是接收的数据// TODO: 做具体的逻辑 on_uart3_recv}}COM3.RX_Cnt = 0;}
}
UART4
if(COM4.RX_TimeOut > 0) {//超时计数if(--COM4.RX_TimeOut == 0) {if(COM4.RX_Cnt > 0) {for(i=0; i<COM4.RX_Cnt; i++) {// TODO: RX4_Buffer[i]存的是接收的数据// TODO: 做具体的逻辑 on_uart4_recv}}COM4.RX_Cnt = 0;}
}
发送
UART1
TX1_write2buff(xx);// 写一个byte
PrintString1(""); // 写字符串
UART2
TX2_write2buff(xx);// 写一个byte
PrintString2(""); // 写字符串
UART3
TX3_write2buff(xx);// 写一个byte
PrintString3(""); // 写字符串
UART4
TX4_write2buff(xx);// 写一个byte
PrintString4(""); // 写字符串
配置printf
保留用到的UART宏
#define UART1 1 //使用哪些串口就开对应的定义,不用的串口可屏蔽掉定义,节省资源
//#define UART2 2
//#define UART3 3
//#define UART4 4
指定printf
函数使用UART1
串口
#define PRINTF_SELECT UART1 //选择 printf 函数所使用的串口,参数 UART1~UART4
Timer操作
导入依赖
void Timer_config(void)
{TIM_InitTypeDef TIM_InitStructure; //结构定义//定时器1做16位自动重装, 中断频率为1000HZTIM_InitStructure.TIM_Mode = TIM_16BitAutoReload; //指定工作模式, TIM_16BitAutoReload,TIM_16Bit,TIM_8BitAutoReload,TIM_T1StopTIM_InitStructure.TIM_ClkSource = TIM_CLOCK_1T; //指定时钟源, TIM_CLOCK_1T,TIM_CLOCK_12T,TIM_CLOCK_ExtTIM_InitStructure.TIM_ClkOut = DISABLE; //是否输出高速脉冲, ENABLE或DISABLETIM_InitStructure.TIM_Value = 65536UL - (MAIN_Fosc / 1000); //初值,TIM_InitStructure.TIM_Run = ENABLE; //是否初始化后启动定时器, ENABLE或DISABLETimer_Inilize(Timer1,&TIM_InitStructure); //初始化Timer1 Timer0,Timer1,Timer2,Timer3,Timer4NVIC_Timer1_Init(ENABLE,Priority_0); //中断使能, ENABLE/DISABLE; 优先级(低到高) Priority_0,Priority_1,Priority_2,Priority_3
}
Timer.c
Timer.h
Timer_Isr.c
NVIC.c
NVIC.h
#include "Timer.h"
#include "NVIC.h"
初始化
Timer0
void Timer_config(void)
{TIM_InitTypeDef TIM_InitStructure; //结构定义//定时器0做16位自动重装, 中断频率为1000HZTIM_InitStructure.TIM_Mode = TIM_16BitAutoReload; //指定工作模式, TIM_16BitAutoReload,TIM_16Bit,TIM_8BitAutoReload,TIM_16BitAutoReloadNoMaskTIM_InitStructure.TIM_ClkSource = TIM_CLOCK_1T; //指定时钟源, TIM_CLOCK_1T,TIM_CLOCK_12T,TIM_CLOCK_ExtTIM_InitStructure.TIM_ClkOut = DISABLE; //是否输出高速脉冲, ENABLE或DISABLETIM_InitStructure.TIM_Value = 65536UL - (MAIN_Fosc / 1000UL); //初值,TIM_InitStructure.TIM_Run = ENABLE; //是否初始化后启动定时器, ENABLE或DISABLETimer_Inilize(Timer0,&TIM_InitStructure); //初始化Timer0 Timer0,Timer1,Timer2,Timer3,Timer4NVIC_Timer0_Init(ENABLE,Priority_0); //中断使能, ENABLE/DISABLE; 优先级(低到高) Priority_0,Priority_1,Priority_2,Priority_3
}
Timer1
void Timer_config(void)
{TIM_InitTypeDef TIM_InitStructure; //结构定义//定时器1做16位自动重装, 中断频率为1000HZTIM_InitStructure.TIM_Mode = TIM_16BitAutoReload; //指定工作模式, TIM_16BitAutoReload,TIM_16Bit,TIM_8BitAutoReload,TIM_T1StopTIM_InitStructure.TIM_ClkSource = TIM_CLOCK_1T; //指定时钟源, TIM_CLOCK_1T,TIM_CLOCK_12T,TIM_CLOCK_ExtTIM_InitStructure.TIM_ClkOut = DISABLE; //是否输出高速脉冲, ENABLE或DISABLETIM_InitStructure.TIM_Value = 65536UL - (MAIN_Fosc / 1000); //初值,TIM_InitStructure.TIM_Run = ENABLE; //是否初始化后启动定时器, ENABLE或DISABLETimer_Inilize(Timer1,&TIM_InitStructure); //初始化Timer1 Timer0,Timer1,Timer2,Timer3,Timer4NVIC_Timer1_Init(ENABLE,Priority_0); //中断使能, ENABLE/DISABLE; 优先级(低到高) Priority_0,Priority_1,Priority_2,Priority_3
}
Timer2
void Timer_config(void)
{TIM_InitTypeDef TIM_InitStructure; //结构定义//定时器2做16位自动重装, 中断频率为1000HZTIM_InitStructure.TIM_ClkSource = TIM_CLOCK_1T; //指定时钟源, TIM_CLOCK_1T,TIM_CLOCK_12T,TIM_CLOCK_ExtTIM_InitStructure.TIM_ClkOut = DISABLE; //是否输出高速脉冲, ENABLE或DISABLETIM_InitStructure.TIM_Value = 65536UL - (MAIN_Fosc / 1000); //初值TIM_InitStructure.TIM_PS = 0; //8位预分频器(n+1), 0~255, (注意:并非所有系列都有此寄存器,详情请查看数据手册)TIM_InitStructure.TIM_Run = ENABLE; //是否初始化后启动定时器, ENABLE或DISABLETimer_Inilize(Timer2,&TIM_InitStructure); //初始化Timer2 Timer0,Timer1,Timer2,Timer3,Timer4NVIC_Timer2_Init(ENABLE,NULL); //中断使能, ENABLE/DISABLE; 无优先级
}
Timer3
void Timer_config(void)
{TIM_InitTypeDef TIM_InitStructure; //结构定义//定时器3做16位自动重装, 中断频率为100HZTIM_InitStructure.TIM_ClkSource = TIM_CLOCK_12T; //指定时钟源, TIM_CLOCK_1T,TIM_CLOCK_12T,TIM_CLOCK_ExtTIM_InitStructure.TIM_ClkOut = DISABLE; //是否输出高速脉冲, ENABLE或DISABLETIM_InitStructure.TIM_Value = 65536UL - (MAIN_Fosc / (100*12)); //初值TIM_InitStructure.TIM_PS = 0; //8位预分频器(n+1), 0~255, (注意:并非所有系列都有此寄存器,详情请查看数据手册)TIM_InitStructure.TIM_Run = ENABLE; //是否初始化后启动定时器, ENABLE或DISABLETimer_Inilize(Timer3,&TIM_InitStructure); //初始化Timer3 Timer0,Timer1,Timer2,Timer3,Timer4NVIC_Timer3_Init(ENABLE,NULL); //中断使能, ENABLE/DISABLE; 无优先级
}
Timer4
void Timer_config(void)
{TIM_InitTypeDef TIM_InitStructure; //结构定义//定时器4做16位自动重装, 中断频率为50HZTIM_InitStructure.TIM_ClkSource = TIM_CLOCK_12T; //指定时钟源, TIM_CLOCK_1T,TIM_CLOCK_12T,TIM_CLOCK_ExtTIM_InitStructure.TIM_ClkOut = DISABLE; //是否输出高速脉冲, ENABLE或DISABLETIM_InitStructure.TIM_Value = 65536UL - (MAIN_Fosc / (50*12)); //初值TIM_InitStructure.TIM_PS = 0; //8位预分频器(n+1), 0~255, (注意:并非所有系列都有此寄存器,详情请查看数据手册)TIM_InitStructure.TIM_Run = ENABLE; //是否初始化后启动定时器, ENABLE或DISABLETimer_Inilize(Timer4,&TIM_InitStructure); //初始化Timer4 Timer0,Timer1,Timer2,Timer3,Timer4NVIC_Timer4_Init(ENABLE,NULL); //中断使能, ENABLE/DISABLE; 无优先级
}
实现中断函数
以Timer0为例:
方式1:
修改Timer_Isr.c
实现中断函数的调用,并在main.c
中声明实现timer0_call
函数
extern void timer0_call();//========================================================================
// 函数: Timer0_ISR_Handler
// 描述: Timer0中断函数.
// 参数: none.
// 返回: none.
// 版本: V1.0, 2020-09-23
//========================================================================
void Timer0_ISR_Handler (void) interrupt TMR0_VECTOR //进中断时已经清除标志
{// TODO: 在此处添加用户代码timer0_call();
}
然后在main.c
中实现timer0_call
:
void timer0_call(){// TODO: 在此处添加用户代码
}
方式2:
直接在main.c
中实现interrupt
函数(记得删掉或注释掉Timer_Isr.c
中对应的中断函数)
void Timer0_ISR (void) interrupt TMR0_VECTOR //进中断时已经清除标志
{// TODO: 在此处添加用户代码
}
PWM操作
依赖及头文件
#include "STC8H_PWM.h"
#include "NVIC.h"
#include "Switch.h"
扩展寄存器访问使能
EAXSFR(); /* 扩展寄存器访问使能 */
初始化PWMA
#define PERIOD (MAIN_Fosc / 1000)
PWMx_Duty dutyA;
void PWM_config(void)
{PWMx_InitDefine PWMx_InitStructure;// 配置PWM1PWMx_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_MODE2PWMx_InitStructure.PWM_Duty = dutyA.PWM1_Duty; //PWM占空比时间, 0~PeriodPWMx_InitStructure.PWM_EnoSelect = ENO1P | ENO1N; //输出通道选择, ENO1P,ENO1N,ENO2P,ENO2N,ENO3P,ENO3N,ENO4P,ENO4N / ENO5P,ENO6P,ENO7P,ENO8PPWM_Configuration(PWM1, &PWMx_InitStructure); //初始化PWM// 配置PWM2PWMx_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_MODE2PWMx_InitStructure.PWM_Duty = dutyA.PWM2_Duty; //PWM占空比时间, 0~PeriodPWMx_InitStructure.PWM_EnoSelect = ENO2P | ENO2N; //输出通道选择, ENO1P,ENO1N,ENO2P,ENO2N,ENO3P,ENO3N,ENO4P,ENO4N / ENO5P,ENO6P,ENO7P,ENO8PPWM_Configuration(PWM2, &PWMx_InitStructure); //初始化PWM// 配置PWM3PWMx_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_MODE2PWMx_InitStructure.PWM_Duty = dutyA.PWM3_Duty; //PWM占空比时间, 0~PeriodPWMx_InitStructure.PWM_EnoSelect = ENO3P | ENO3N; //输出通道选择, ENO1P,ENO1N,ENO2P,ENO2N,ENO3P,ENO3N,ENO4P,ENO4N / ENO5P,ENO6P,ENO7P,ENO8PPWM_Configuration(PWM3, &PWMx_InitStructure); // 配置PWM4PWMx_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_MODE2PWMx_InitStructure.PWM_Duty = dutyA.PWM4_Duty; //PWM占空比时间, 0~PeriodPWMx_InitStructure.PWM_EnoSelect = ENO4P | ENO4N; //输出通道选择, ENO1P,ENO1N,ENO2P,ENO2N,ENO3P,ENO3N,ENO4P,ENO4N / ENO5P,ENO6P,ENO7P,ENO8PPWM_Configuration(PWM4, &PWMx_InitStructure);// 配置PWMAPWMx_InitStructure.PWM_Period = PERIOD - 1; //周期时间, 0~65535PWMx_InitStructure.PWM_DeadTime = 0; //死区发生器设置, 0~255PWMx_InitStructure.PWM_MainOutEnable= ENABLE; //主输出使能, ENABLE,DISABLEPWMx_InitStructure.PWM_CEN_Enable = ENABLE; //使能计数器, ENABLE,DISABLEPWM_Configuration(PWMA, &PWMx_InitStructure); //初始化PWM通用寄存器, PWMA,PWMB// 切换PWM通道PWM1_SW(PWM1_SW_P10_P11); //PWM1_SW_P10_P11,PWM1_SW_P20_P21,PWM1_SW_P60_P61PWM2_SW(PWM2_SW_P12_P13); //PWM2_SW_P12_P13,PWM2_SW_P22_P23,PWM2_SW_P62_P63PWM3_SW(PWM3_SW_P14_P15); //PWM3_SW_P14_P15,PWM3_SW_P24_P25,PWM3_SW_P64_P65PWM4_SW(PWM4_SW_P16_P17); //PWM4_SW_P16_P17,PWM4_SW_P26_P27,PWM4_SW_P66_P67,PWM4_SW_P34_P33// 初始化PWMA的中断NVIC_PWM_Init(PWMA,DISABLE,Priority_0);
}
- 总配置中的
PWM_Period
, 配置周期计数。#define PERIOD (MAIN_Fosc / 1000)
1000 表示1s执行1000次。此处为计数值。- PWM1_Duty表示占空比,1个周期中高电平或者低电平出现的百分比,此处为百分比的计数值。
初始化PWMB
#define PERIOD (MAIN_Fosc / 1000)
PWMx_Duty dutyB;
void PWM_config(void)
{PWMx_InitDefine PWMx_InitStructure;// 配置PWM5PWMx_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_MODE2PWMx_InitStructure.PWM_Duty = dutyB.PWM5_Duty; //PWM占空比时间, 0~PeriodPWMx_InitStructure.PWM_EnoSelect = ENO5P; //输出通道选择, ENO1P,ENO1N,ENO2P,ENO2N,ENO3P,ENO3N,ENO4P,ENO4N / ENO5P,ENO6P,ENO7P,ENO8PPWM_Configuration(PWM5, &PWMx_InitStructure); //初始化PWM, PWMA,PWMB// 配置PWM6PWMx_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_MODE2PWMx_InitStructure.PWM_Duty = dutyB.PWM6_Duty; //PWM占空比时间, 0~PeriodPWMx_InitStructure.PWM_EnoSelect = ENO6P; //输出通道选择, ENO1P,ENO1N,ENO2P,ENO2N,ENO3P,ENO3N,ENO4P,ENO4N / ENO5P,ENO6P,ENO7P,ENO8PPWM_Configuration(PWM6, &PWMx_InitStructure); //初始化PWM, PWMA,PWMB// 配置PWM7PWMx_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_MODE2PWMx_InitStructure.PWM_Duty = dutyB.PWM7_Duty; //PWM占空比时间, 0~PeriodPWMx_InitStructure.PWM_EnoSelect = ENO7P; //输出通道选择, ENO1P,ENO1N,ENO2P,ENO2N,ENO3P,ENO3N,ENO4P,ENO4N / ENO5P,ENO6P,ENO7P,ENO8PPWM_Configuration(PWM7, &PWMx_InitStructure); //初始化PWM, PWMA,PWMB// 配置PWM8PWMx_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_MODE2PWMx_InitStructure.PWM_Duty = dutyB.PWM8_Duty; //PWM占空比时间, 0~PeriodPWMx_InitStructure.PWM_EnoSelect = ENO8P; //输出通道选择, ENO1P,ENO1N,ENO2P,ENO2N,ENO3P,ENO3N,ENO4P,ENO4N / ENO5P,ENO6P,ENO7P,ENO8PPWM_Configuration(PWM8, &PWMx_InitStructure); //初始化PWM, PWMA,PWMB// 配置PWMBPWMx_InitStructure.PWM_Period = PERIOD - 1; //周期时间, 0~65535PWMx_InitStructure.PWM_DeadTime = 0; //死区发生器设置, 0~255PWMx_InitStructure.PWM_MainOutEnable= ENABLE; //主输出使能, ENABLE,DISABLEPWMx_InitStructure.PWM_CEN_Enable = ENABLE; //使能计数器, ENABLE,DISABLEPWM_Configuration(PWMB, &PWMx_InitStructure); //初始化PWM通用寄存器, PWMA,PWMB// 切换PWM通道PWM5_SW(PWM5_SW_P20); //PWM5_SW_P20,PWM5_SW_P17,PWM5_SW_P00,PWM5_SW_P74PWM6_SW(PWM6_SW_P21); //PWM6_SW_P21,PWM6_SW_P54,PWM6_SW_P01,PWM6_SW_P75PWM7_SW(PWM7_SW_P22); //PWM7_SW_P22,PWM7_SW_P33,PWM7_SW_P02,PWM7_SW_P76PWM8_SW(PWM8_SW_P23); //PWM8_SW_P23,PWM8_SW_P34,PWM8_SW_P03,PWM8_SW_P77// 初始化PWMB的中断NVIC_PWM_Init(PWMB,DISABLE,Priority_0);
}
ADC操作
初始化
/******************* AD配置函数 *******************/
void ADC_config(void)
{ADC_InitTypeDef ADC_InitStructure; //结构定义ADC_InitStructure.ADC_SMPduty = 31; //ADC 模拟信号采样时间控制, 0~31(注意: SMPDUTY 一定不能设置小于 10)ADC_InitStructure.ADC_CsSetup = 0; //ADC 通道选择时间控制 0(默认),1ADC_InitStructure.ADC_CsHold = 1; //ADC 通道选择保持时间控制 0,1(默认),2,3ADC_InitStructure.ADC_Speed = ADC_SPEED_2X1T; //设置 ADC 工作时钟频率 ADC_SPEED_2X1T~ADC_SPEED_2X16TADC_InitStructure.ADC_AdjResult = ADC_RIGHT_JUSTIFIED; //ADC结果调整, ADC_LEFT_JUSTIFIED,ADC_RIGHT_JUSTIFIEDADC_Inilize(&ADC_InitStructure); //初始化ADC_PowerControl(ENABLE); //ADC电源开关, ENABLE或DISABLENVIC_ADC_Init(DISABLE,Priority_0); //中断使能, ENABLE/DISABLE; 优先级(低到高) Priority_0,Priority_1,Priority_2,Priority_3
}
获取值
u16 result = Get_ADCResult(chn); // chn: ADC_CH0, ADC_CH1, ADC_CH2 .... ADC_CH15
计算电压
float v = result * 基准电压 / 采样精度;
- 2.5为参考电压值,是实际情况而定
- 基准电压:根据电路情况确定,基准电压芯片默认2.5V
- 采样精度: 12位adc
- 2^12=4096
I2C操作
初始化
拷贝如下文件:
I2C.c
I2C.h
NVIC.c
NVIC.h
Switch.h
GPIO初始化
void GPIO_config(void) {GPIO_InitTypeDef GPIO_InitStructure; //结构定义GPIO_InitStructure.Pin = GPIO_Pin_2 | GPIO_Pin_3; //指定要初始化的IO,GPIO_InitStructure.Mode = GPIO_OUT_OD; //指定IO的输入或输出方式,GPIO_PullUp,GPIO_HighZ,GPIO_OUT_OD,GPIO_OUT_PPGPIO_Inilize(GPIO_P3, &GPIO_InitStructure);//初始化
}
I2C初始化
/**************** I2C初始化函数 *****************/
void I2C_config(void)
{I2C_InitTypeDef I2C_InitStructure;I2C_InitStructure.I2C_Mode = I2C_Mode_Master; //主从选择 I2C_Mode_Master, I2C_Mode_SlaveI2C_InitStructure.I2C_Enable = ENABLE; //I2C功能使能, ENABLE, DISABLEI2C_InitStructure.I2C_MS_WDTA = DISABLE; //主机使能自动发送, ENABLE, DISABLEI2C_InitStructure.I2C_Speed = 13; //总线速度=Fosc/2/(Speed*2+4), 0~63// 400k, 24M => 13I2C_Init(&I2C_InitStructure);NVIC_I2C_Init(I2C_Mode_Master,DISABLE,Priority_0); //主从模式, I2C_Mode_Master, I2C_Mode_Slave; 中断使能, ENABLE/DISABLE; 优先级(低到高) Priority_0,Priority_1,Priority_2,Priority_3I2C_SW(I2C_P33_P32); //I2C_P14_P15,I2C_P24_P25,I2C_P33_P32
}
INT中断
外部中断编写
1. 引入外部中断库函数
a. Exti.hExti.cExti_Isr.c
b. NVIC.h NVIC.c
2.配置外部中断
#include "Exti.h"
#include "NVIC.h"/******************** INT配置 ********************/
void Exti_config(void)
{EXTI_InitTypeDef Exti_InitStructure; //结构定义Exti_InitStructure.EXTI_Mode = EXT_MODE_RiseFall;//中断模式, EXT_MODE_RiseFall,EXT_MODE_FallExt_Inilize(EXT_INT0,&Exti_InitStructure); //初始化NVIC_INT0_Init(ENABLE,Priority_0); //中断使能, ENABLE/DISABLE; 优先级(低到高) Priority_0,Priority_1,Priority_2,Priority_3
}
void ext_int0_call(void) {// 当中断触发时的实现逻辑
}
3.调用中断触发函数
extern void ext_int0_call();
//========================================================================
// 函数: INT0_ISR_Handler
// 描述: INT0中断函数.
// 参数: none.
// 返回: none.
// 版本: V1.0, 2020-09-23
//========================================================================
void INT0_ISR_Handler (void) interrupt INT0_VECTOR //进中断时已经清除标志
{ext_int0_call();
}
外部中断 | 引脚 | 备注 |
INT0 | P3.2 | 支持上升沿和下降沿中断 |
INT1 | P3.3 | 支持上升沿和下降沿中断 |
INT2 | P3.6 | 只支持下降沿中断 |
INT3 | P3.7 | 只支持下降沿中断 |
INT4 | P3.0 | 只支持下降沿中断 |