本章使用芯片:STC8H8K64U核心板
芯片手册:点此查看
Keil 开发环境配置:点此查看
本章学习内容:利用库函数,开发C程序,实现呼吸灯效果。
需求:使用串口来控制呼吸灯效果,如果串口接收的数据为1,则奇数灯亮;如为0,则偶数位灯亮。
#include "NVIC.h"
#include "GPIO.h"
#include "Config.h"
#include "Switch.h"
#include "STC8H_PWM.h"
#include "UART.h"
#include "Delay.h"
#define PEROID MAIN_Fosc/1000 //主频周期
#define LED_SW P45 //总开关接的P45引脚,要设置为低电平
#define LED1 P27
#define LED2 P26
#define LED3 P15
#define LED4 P14
#define LED5 P23
#define LED6 P22
#define LED7 P21
#define LED8 P20
PWMx_Duty duty;
void GPIO_Config(){
GPIO_InitTypeDef init;
init.Mode=GPIO_OUT_PP;//推挽输出
init.Pin=GPIO_Pin_5;
GPIO_Inilize(GPIO_P4, &init);
init.Pin=GPIO_Pin_7 | GPIO_Pin_6 |GPIO_Pin_3 |GPIO_Pin_2 |GPIO_Pin_1 |GPIO_Pin_0 ;
GPIO_Inilize(GPIO_P2, &init);
init.Pin=GPIO_Pin_5 | GPIO_Pin_4;
GPIO_Inilize(GPIO_P1, &init);
}
void UART_Config(){
COMx_InitDefine init;
init.UART_Mode = UART_8bit_BRTx;
init.UART_BRT_Use=BRT_Timer1;
init.UART_BaudRate=115200;
init.Morecommunicate=DISABLE;
init.UART_RxEnable=ENABLE;
init.BaudRateDouble=DISABLE;
UART_Configuration(UART1, &init);
// UART会触发中断,所以要在NVIC中找到中断并配置优先级,URAT关系到写数据,所以优先级要高于其他任务
NVIC_UART1_Init(ENABLE, Priority_3);
// 切换引脚,本实验电路板默认就是PIN脚30、31 ,也可以不写,但有多组时必须配置
UART1_SW(UART1_SW_P30_P31)
}
void PWM_Config(){
PWMx_InitDefine init;
init.PWM_Mode=CCMRn_PWM_MODE1; //模式,通常选择模式1或者模式2
init.PWM_Period=PEROID-1;//周期时间, 0~65535
init.PWM_Duty=0; //PWM占空比时间, 0~Period
init.PWM_DeadTime=0;
init.PWM_EnoSelect=ENO1P| ENO1N| ENO2P| ENO2N| ENO3P| ENO3N| ENO4P| ENO4N;
init.PWM_CEN_Enable=ENABLE;
init.PWM_MainOutEnable=ENABLE;
// 配置PWMA和PWM1、PWM2、PWM3、PWM4
PWM_Configuration(PWMA,&init);
PWM_Configuration(PWM1,&init);
PWM_Configuration(PWM2,&init);
PWM_Configuration(PWM3,&init);
PWM_Configuration(PWM4,&init);
// 初始化PWMA的中断
NVIC_PWM_Init(PWMA, DISABLE, Priority_0);
//切换PWM引脚
PWM1_SW(PWM1_SW_P20_P21);
PWM2_SW(PWM2_SW_P22_P23);
PWM3_SW(PWM3_SW_P14_P15);
PWM4_SW(PWM4_SW_P26_P27);
}
void main(){
int percent=0; //单片机中要使用的变量必须定义在离函数名最近的位置,否则编译时会报错未定义或重复定义
int direction=1;
EAXSFR(); //扩展寄存器访问使能, 使用PWM功能必须配置,且要配置在前面,否则可能无呼吸效果
EA=1; //中断使能
GPIO_Config();
UART_Config();
PWM_Config();
// 总开关
LED_SW=0;
//点亮所有灯
LED1 = LED2 = LED3 = LED4 = LED5 = LED6 = LED7 = LED8 = 0;
while (1)
{
// 倒计时5次确保缓冲区内此时没正在接收数据
if (COM1.RX_TimeOut>0 &&--COM1.RX_TimeOut==0){
// 判断缓冲区有数据
if (COM1.RX_Cnt>0){
if (RX1_Buffer[0]==0){
direction=1;
}
else if (RX1_Buffer[0]==1)
{
direction=-1;
}
// 让duty_percent一直在0-100来回往返
if (percent>=100){
percent=100;
}else if(percent<=0){
percent=0;
}
percent +=direction;
// 修改PWM的duty并更新
duty.PWM1_Duty=PEROID*percent/100;
duty.PWM2_Duty=PEROID*percent/100;
duty.PWM3_Duty=PEROID*percent/100;
duty.PWM4_Duty=PEROID*percent/100;
UpdatePwm(PWMA, &duty);
//缓冲区数据拿完后要将数据长度置为0
COM1.RX_Cnt=0;
//设置延时
delay_ms(250);
delay_ms(250);
}
}
}
}
}