我用这个项目学习stm8s105芯片开发后的实践项目。
本项目采用直流电机控制的风扇PWM控制档位,设置为三档,三档LED用数码管显示相应的档位。
代码直接放在下面
pwm.c
#include "pwm.h"
//TIM1初始化 void TIM1_PWM_Init(u16 pre,u16 per) { TIM1_TimeBaseInit(pre , //配置预分频率为 定时器时钟为 16Mhz / 763 = 20997 HZ TIM1_COUNTERMODE_UP , //向上计数 per, ///自动重载值 0 ); TIM1_OC1Init(TIM1_OCMODE_PWM2 , //设置为PWM2输出模式 TIM1_OUTPUTSTATE_ENABLE , ///输出使能 TIM1_OUTPUTNSTATE_ENABLE , 500 , ///设置为0 TIM1_OCPOLARITY_HIGH ,//OC1 HI TIM1_OCNPOLARITY_LOW , TIM1_OCIDLESTATE_SET , TIM1_OCNIDLESTATE_RESET ); TIM1_CCxCmd(TIM1_CHANNEL_1 , ENABLE); //使能通道1PWM信号输出 TIM1_CtrlPWMOutputs(ENABLE); TIM1_Cmd(ENABLE); }
//TIM2初始化 void TIM2_PWM_Init(void) { TIM2_TimeBaseInit(TIM2_PRESCALER_16 , //16Mhz / 16 = 1MHZ 500 ///自动重载值 //频率是2Kh ); ///定时器2通道2PWM输出 TIM2_OC2Init(TIM2_OCMODE_PWM2 , //设置为PWM2输出模式 TIM2_OUTPUTSTATE_ENABLE , ///输出使能 0 , ///设置为0 TIM2_OCPOLARITY_HIGH //OC1 HI ); TIM2_CCxCmd(TIM2_CHANNEL_2 , ENABLE); //使能TIM2_CH2PWM输出 TIM2_Cmd(ENABLE); }
//TIM3初始化 void TIM3_PWM_Init(void) { TIM3_TimeBaseInit(TIM3_PRESCALER_16 , //16Mhz / 16 = 1 500 ///自动重载值 ); ///定时器3通道1PWM输出 TIM3_OC1Init(TIM3_OCMODE_PWM2 , //设置为PWM2输出模式 TIM3_OUTPUTSTATE_ENABLE , ///输出使能 0 , ///设置为0 TIM3_OCPOLARITY_HIGH //OC1 HI ); TIM3_CCxCmd(TIM3_CHANNEL_1 , ENABLE); //使能TIM3_CH1PWM输出 TIM3_Cmd(ENABLE); }
pwm.h
#ifndef _pwm_H #define _pwm_H
#include "stm8s.h"
void TIM1_PWM_Init(u16 pre,u16 per); void TIM2_PWM_Init(void); void TIM3_PWM_Init(void);
#endif
静态数码管显示
smg.c
#include "smg.h" #include "delay.h"
u8 smgduan[17] = {0x3f,0x06,0x5b,0x4f,0x66,0x6d,0x7d,0x07, 0x7f,0x6f,0x77,0x7c,0x39,0x5e,0x79,0x71};// 显示0~F的值
/// void StaticSMG_Init(void) { //初始化PB0-PB77快速推拉输出高模式 GPIO_Init(GPIOB , GPIO_PIN_ALL , GPIO_MODE_OUT_PP_HIGH_FAST); }
//// //参数:dat:显示段码值 void StaticSMG_Display(u8 dat) { GPIO_Write(GPIOB,dat); }
smg.h
#ifndef _smg_H #define _smg_H
#include "stm8s.h"
///38译码器管脚定义 #define LSA_SETH GPIO_WriteHigh(GPIOD , GPIO_PIN_0) #define LSA_SETL GPIO_WriteLow(GPIOD , GPIOPIN_0)
#define LSB_SETH GPIO_WriteHigh(GPIOD , GPIO_PIN_1) #define LSB_SETL GPIO_WriteLow(GPIOD , GPIO_PIN_1)
#define LSC_SETH GPIO_WriteHigh(GPIOD , GPIO_PIN_2) #define LSC_SETL GPIO_WriteLow(GPIOD , GPIO_PIN_2)
void StaticSMG_Init(void); void StaticSMG_Display(u8 dat);
#endif
直流电机模块
motor.c
#include "motor.h"
void ZHILIU_Init(void) { GPIO_Init(GPIOC , GPIO_PIN_2 , GPIO_MODE_OUT_PP_HIGH_FAST); }
motor.h
#ifndef _motor_H #define _motor_H
#include "stm8s.h"
/* #define ZHILIU_ON (GPIOC->ODR|=GPIO_PIN_2) #define ZHILIU_OFF (GPIOC->ODR&=~GPIO_PIN_2) */
#define ZHILIU_ON() GPIO_WriteHigh(GPIOC , GPIO_PIN_2) //电机开 #define ZHILIU_OFF() GPIO_WriteLow(GPIOC , GPIO_PIN_2) //电机关
void ZHILIU_Init(void);
#endif
led.c
#include "led.h"
void LED_Init(void) { //设置PC1为快速推挽输出 ,LED1 GPIO_Init(GPIOC , GPIO_PIN_1 , GPIO_MODE_OUT_PP_HIGH_FAST); //设置PC2为快速推挽输出 ,LED2 GPIO_Init(GPIOC , GPIO_PIN_2 , GPIO_MODE_OUT_PP_HIGH_FAST); //设置PC3为快速推挽输出 ,LED3 GPIO_Init(GPIOC , GPIO_PIN_3 , GPIO_MODE_OUT_PP_HIGH_FAST); GPIO_Init(GPIOC , GPIO_PIN_4 , GPIO_MODE_OUT_PP_HIGH_FAST); }
led.h
#ifndef _led_H #define _led_H
#include "stm8s.h"
#define LED1_ON() GPIO_WriteLow(GPIOC , GPIO_PIN_1) //LED1亮 #define LED1_OFF() GPIO_WriteHigh(GPIOC , GPIO_PIN_1) //LED1灭 #define LED1_TOGGLE GPIO_WriteReverse(GPIOC , GPIO_PIN_1) //LED1状态取反
#define LED2_ON() GPIO_WriteLow(GPIOC , GPIO_PIN_2) //LED2亮 #define LED2_OFF() GPIO_WriteHigh(GPIOC , GPIO_PIN_2) //LED2灭 #define LED2_TOGGLE GPIO_WriteReverse(GPIOC , GPIO_PIN_2) //LED2状态取反
#define LED3_ON() GPIO_WriteLow(GPIOC , GPIO_PIN_3) //LED3亮 #define LED3_OFF() GPIO_WriteHigh(GPIOC , GPIO_PIN_3) //LED3灭 #define LED3_TOGGLE GPIO_WriteReverse(GPIOC , GPIO_PIN_3) //LED3状态取反
#define LED4_ON() GPIO_WriteLow(GPIOC , GPIO_PIN_4) //LED4亮 #define LED4_OFF() GPIO_WriteHigh(GPIOC , GPIO_PIN_4) //LED4灭 #define LED4_TOGGLE GPIO_WriteReverse(GPIOC , GPIO_PIN_4) //LED4状态取反
void LED_Init(void);
#endif
key.c
#include "key.h"
void KEY_Init(void) { //设置PE6为不含中断带上拉电阻输入 GPIO_Init(GPIOE , GPIO_PIN_6 , GPIO_MODE_IN_PU_NO_IT); //设置PE7为不含中断带上拉电阻输入 GPIO_Init(GPIOE , GPIO_PIN_7 , GPIO_MODE_IN_PU_NO_IT); }
key.h
#ifndef _key_H #define _key_H
#include "stm8s.h"
#define KEY1 GPIO_ReadInputPin(GPIOE,GPIO_PIN_6) #define KEY2 GPIO_ReadInputPin(GPIOE,GPIO_PIN_7)
//定义各个按键值 #define KEY1_VALUE 1 #define KEY2_VALUE 2
void KEY_Init(void); u8 KEY_Scan(u8 mode);
#endif
delay.c
#include "delay.h"
void delay_ms(unsigned int ms) { unsigned int x , y; for(x = ms; x > 0; x--) /* 通过一定周期循环进行延时*/ for(y = 3000 ; y > 0 ; y--); }
主函数
main.c
#include "stm8s.h" /* 添加库函数头文件 */ #include "delay.h" #include "motor.h" #include "usart.h" #include "time.h" #include "key.h" #include "pwm.h" #include "led.h" #include "smg.h"
/***************************添加数码管显示和led灯显示档位*****************/ u8 smgduan[17]={0x3f,0x06,0x5b,0x4f,0x66,0x6d,0x7d,0x07, 0x7f,0x6f,0x77,0x7c,0x39,0x5e,0x79,0x71};//显示0~F的值 // u16 i = 0; u8 t=0; //内部时钟为1分频 = 16Mhz CLK_SYSCLKConfig(CLK_PRESCALER_HSIDIV1); USART2_Init(9600); //初始化USART2 , 并设置波特率为9600 LED_Init(); ZHILIU_Init(); KEY_Init(); StaticSMG_Init(); TIM1_PWM_Init(15,500);//频率是2Kh enableInterrupts(); //使能系统中断 while(1) { if(KEY1 == 0) { delay_ms(20); if(KEY1 == 0) { t++; t%=4; //t = t%4 将t的值限制在0-3之间 switch(t)
{ case 0: TIM1_SetCompare1(500); LED2_OFF(); LED3_OFF(); LED4_OFF(); StaticSMG_Display(~smgduan[0]); break; case 1: TIM1_SetCompare1(300); LED2_ON(); LED3_OFF(); LED4_OFF(); StaticSMG_Display(~smgduan[1]); break; case 2: TIM1_SetCompare1(100); LED2_OFF(); LED3_ON(); LED4_OFF(); StaticSMG_Display(~smgduan[2]); break; case 3: TIM1_SetCompare1(0); LED2_OFF(); LED3_OFF(); LED4_ON(); StaticSMG_Display(~smgduan[3]);
break; } while(KEY1 == 0); } } } }
//是一个宏定义;在固件库中,它的作用就是检测传递给函数的参数是否是有效的参数 void assert_failed(u8* file, u32 line) { while (1) { } }