STC8模板代码

目录

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.cNVIC.hSwitch.hType_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
}
  1. Timer.cTimer.hTimer_Isr.c
  2. NVIC.cNVIC.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操作

初始化

拷贝如下文件:

  1. I2C.c I2C.h
  2. NVIC.c NVIC.h
  3. 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

只支持下降沿中断

 

 

 

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/221478.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

Apache DolphinScheduler 社区荣获 “2023 年度优秀开源技术团队“ 奖项

在开源社区日益繁荣的今天&#xff0c;我们非常荣幸地宣布&#xff1a;Apache DolphinScheduler 社区在 OSCHINA 平台的评选中荣获了“2023 年度优秀开源技术团队”奖项。这一奖项反映了我们社区在过去一年里在内容发表的深度与广度、活动运营影响力以及对开源文化的推广方面所…

AGILE-SCRUM

一个复杂的汽车ECU开发。当时开发队伍遍布全球7个国家&#xff0c;10多个地区&#xff0c;需要同时为多款车型定制不同的软件&#xff0c;头疼的地方是&#xff1a; 涉及到多方人员协调&#xff0c;多模块集成和管理不同软件团队使用的设计工具、验证工具&#xff0c;数据、工…

JS-sessionStorage、localStorage和cookie

sessionStorage 仅在浏览器当前窗口关闭之前有效,即使是刷新或者进入该窗口下的的另一个页面&#xff0c;数据也仍然存在&#xff1b;关闭浏览器或到另一个窗口&#xff0c;数据就是不存在的。 // 设置sessionStorage保存到本地&#xff0c;第一个为变量名&#xff0c;第二个是…

实验一 门电路逻辑功能及测试

一、实验目的 1.熟悉门电路逻辑功能. 2.熟悉数字电路学习机及示波器使用方法。 二、实验仪器及材料 1.双踪示波器 2.器件 74LS00 二输入端四与非门 2片 74LS20 四输人端双与非门 1片 74LS86 二输入端四异或门 1片 74LS04 六反相器 1片 …

如何在本地搭建Oracle数据库并实现无公网ip通过PLSQL工具远程连接数据库

文章目录 前言1. 数据库搭建2. 内网穿透2.1 安装cpolar内网穿透2.2 创建隧道映射 3. 公网远程访问4. 配置固定TCP端口地址4.1 保留一个固定的公网TCP端口地址4.2 配置固定公网TCP端口地址4.3 测试使用固定TCP端口地址远程Oracle 正文开始前给大家推荐个网站&#xff0c;前些天发…

基于JAVA的校园电子商城系统论文

摘 要 网络技术和计算机技术发展至今&#xff0c;已经拥有了深厚的理论基础&#xff0c;并在现实中进行了充分运用&#xff0c;尤其是基于计算机运行的软件更是受到各界的关注。加上现在人们已经步入信息时代&#xff0c;所以对于信息的宣传和管理就很关键。因此校园购物信息的…

西南科技大学数字电子技术实验七(4行串行累加器设计及FPGA实现)预习报告

一、计算/设计过程 说明&#xff1a;本实验是验证性实验&#xff0c;计算预测验证结果。是设计性实验一定要从系统指标计算出元件参数过程&#xff0c;越详细越好。用公式输入法完成相关公式内容&#xff0c;不得贴手写图片。&#xff08;注意&#xff1a;从抽象公式直接得出结…

正则表达式入门与实践

文章目录 一、为什么要有正则二、正则表达式基础概念三、Pattern与Matcher类的使用(一)Pattern类的常用方法(二)Matcher类的常用方法四、常用正则规则及其含义(一)规范表示(二)数量表示(三)逻辑运算符五、String对正则表达式的支持六、实践演练(一)匹配给定文本中的…

如何预防最新的.halo勒索病毒感染您的计算机?

导言&#xff1a; 数据的安全性愈发成为人们关注的焦点&#xff0c;而.halo勒索病毒的出现给数字生活带来了严重的威胁。本文91数据恢复将深入介绍.halo勒索病毒的特征&#xff0c;提供有效的数据恢复方法&#xff0c;并分享一些预防措施&#xff0c;助您更好地保护自己的数字…

大数据云计算——Docker环境下部署Hadoop集群及运行集群案列

大数据云计算——Docker环境下部署Hadoop集群及运行集群案列 本文着重介绍了在Docker环境下部署Hadoop集群以及实际案例中的集群运行。首先&#xff0c;文章详细解释了Hadoop的基本概念和其在大数据处理中的重要性&#xff0c;以及为何选择在Docker环境下部署Hadoop集群。接着&…

12.HTML5新特性

HTML5新特性 1.介绍 它是万维网的核心语言、标准通用标记语言下的一个应用超文本标记语言&#xff08;HTML&#xff09;的第五次重大修改。用于取代 HTML4 与 XHTML 的新一代标准版本&#xff0c;所以叫HTML5 HTML5 在狭义上是指新一代的 HTML 标准&#xff0c;在广义上是指…

云原生之深入解析K8s中的微服务项目设计与实现

一、微服务项目的设计 ① 微服务设计的思想 一个单片应用程序将被构建、测试并顺利地通过这些环境。事实证明&#xff0c;一旦投资于将生产路径自动化&#xff0c;那么部署更多的应用程序似乎就不再那么可怕了。请记住&#xff0c;CD的目标之一就是让部署变得无聊&#xff0c…

【亲测可用】实在太快了!如何在Linux下5分钟快速安装MongoDB

简介 MongoDB 是一款介于关系数据库和非关系数据库之间的产品&#xff0c;是非关系数据库当中功能最丰富&#xff0c;最像关系数据库的。他支持的数据结构非常松散&#xff0c;是类似json的bson格式&#xff0c;因此可以存储比较复杂的数据类型。Mongo最大的特点是他支持的查询…

如何参与开源项目

大家好&#xff0c;受卡哥邀请&#xff0c;和大家分享一下开源活动的相关经验。首先简要自我介绍一下&#xff0c;我目前在一所985研二在读&#xff0c;主要学习大数据方向&#xff0c;从去年开始参与开源活动近一年时间&#xff0c;也对多个Apache框架有所贡献。 由于学校或专…

2023最新Java获取微博cookie,可用于爬取文章(扫码登录)

目录 文章最下面含有完整main类代码&#xff0c;和完整控制层代码 一、发送请求获取图片和qrid 二、发送请求确认二维码已被正确扫描 三、携带拿到的alt&#xff0c;发送登录请求&#xff0c;获取cookie 四、main类完整方法代码 五、控制层接口完整代码 文章最下面含有完整…

IP与子网掩码之间的关系

子网掩码用于确认IP所在的网段&#xff0c;网络位与子网掩码相匹配 如果有另一台主机想要与这个IP地址进行通信&#xff0c;这时需要看两台主机的IP地址是否处于同一网段&#xff0c;处于同一网段才能相互ping通。 那么怎么判断是否处于同一网段呢&#xff1f;我们就看子网掩…

提升团队效率,防止员工飞单私单的秘诀!

在如今竞争激烈的商业环境中&#xff0c;每个企业都追求更高的销售业绩和客户满意度。然而&#xff0c;有些员工可能会利用V信等社交工具进行私下交易&#xff0c;导致公司的利益损失和客户信任的瓦解。所以&#xff0c;如何防止员工飞单私单成为了一个需要解决的问题。 在这里…

解决POI导入内部错误方式

目录 1、错误报文&#xff1a; 2、解决方案 参考 3、本人采用的是在配置文件中忽略该报错&#xff0c; 1、错误报文&#xff1a; WARN o.a.poi.openxml4j.opc.ZipPackage - Entry _rels/ is not valid, so this part wont be add to the package. org.apache.poi.openxml4…

FL Studio20官方版怎么下载安装?2024最新版图文详细教程

水果音乐制作软件FL Studio2024是一款功能强大的软件音乐制作环境或数字音频工作站&#xff08;DAW&#xff09;&#xff0c;本文主要针对FL Studio 2024怎么安装&#xff1f;来为大家带来了水果软件FL Studio 2024安装图文详细教程&#xff01;水果音乐制作软件FL Studio2024版…

智能分析/可视化安防监控系统EasyCVR风光互补远程视频监控方案

一、背景需求 在一些偏远地区&#xff0c;也具有视频监控的需求。但是这类场景中&#xff0c;一般无法就近获取市电&#xff0c;如果要长距离拉取市电&#xff0c;建设的成本非常高且长距离传输有安全隐患&#xff0c;因此风光互补远程视频监控方案的需求也较多。利用风光电转…