前言
**本程序设计是基于嵌入式开发板CT117E,stm32f103RBT6。
如果对哪个模块的代码不理解可以点开我的博客查看各个模块的编写思路。
一、试题
二、需要用到的模块
1.LED
代码如下:led.c:
#include "led.h"
void led_init(void)
{
GPIO_InitTypeDef GPIO_InitStructure;
RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOD | RCC_APB2Periph_GPIOC, ENABLE);
/* Configure PD0 and PD2 in output pushpull mode */
GPIO_InitStructure.GPIO_Pin = GPIO_Pin_2;
GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
GPIO_InitStructure.GPIO_Mode = GPIO_Mode_Out_PP;
GPIO_Init(GPIOD, &GPIO_InitStructure);
GPIO_InitStructure.GPIO_Pin = 0xff00;
GPIO_Init(GPIOC, &GPIO_InitStructure);
GPIOC->ODR |=0xff<<8;
GPIOD->ODR |=1<<2;
GPIOD->ODR &=~(1<<2);
}
void led_ctrl(u8 ledx,u8 status) //控制led的亮灭,ledx取值范围:8-15
{
if(status)
{
GPIOC->ODR &=~(1<<ledx);
GPIOD->ODR |=1<<2;
GPIOD->ODR &=~(1<<2);
}
else
{
GPIOC->ODR |=1<<ledx;
GPIOD->ODR |=1<<2;
GPIOD->ODR &=~(1<<2);
}
}
led.h:
#ifndef LED_H
#define LED_H
#include "stm32f10x.h"
void led_init(void);
void led_ctrl(u8 ledx,u8 status);
#endif
2.按键
代码如下:key.c:
#include "key.h"
void key_init(void)
{
GPIO_InitTypeDef GPIO_InitStructure;
RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOA | RCC_APB2Periph_GPIOB, ENABLE);
/* Configure PD0 and PD2 in output pushpull mode */
GPIO_InitStructure.GPIO_Pin = GPIO_Pin_0 | GPIO_Pin_8;
GPIO_InitStructure.GPIO_Mode = GPIO_Mode_IN_FLOATING;
GPIO_Init(GPIOA, &GPIO_InitStructure);
GPIO_InitStructure.GPIO_Pin = GPIO_Pin_1 | GPIO_Pin_2;
GPIO_Init(GPIOB, &GPIO_InitStructure);
}
key.h:
#include "key.h"
#ifndef KEY_H
#define KEY_H
#include "stm32f10x.h"
#define key1 GPIO_ReadInputDataBit(GPIOA,GPIO_Pin_0) //读取按键的状态
#define key2 GPIO_ReadInputDataBit(GPIOA,GPIO_Pin_8)
#define key3 GPIO_ReadInputDataBit(GPIOB,GPIO_Pin_1)
#define key4 GPIO_ReadInputDataBit(GPIOB,GPIO_Pin_8)
void key_init(void);
#endif
3.ADC
代码如下:adc.c:
#include "adc.h"
void adc_init(void)
{
ADC_InitTypeDef ADC_InitStructure;
GPIO_InitTypeDef GPIO_InitStructure;
RCC_APB2PeriphClockCmd(RCC_APB2Periph_ADC1 | RCC_APB2Periph_GPIOA, ENABLE);
/* Configure PC.01, PC.02 and PC.04 (ADC Channel11, Channel12 and Channel14)
as analog input ----------------------------------------------------------*/
GPIO_InitStructure.GPIO_Pin = GPIO_Pin_5 | GPIO_Pin_4;
GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AIN;
GPIO_Init(GPIOA, &GPIO_InitStructure);
/* ADC1 configuration ------------------------------------------------------*/
ADC_InitStructure.ADC_Mode = ADC_Mode_Independent;
ADC_InitStructure.ADC_ScanConvMode = ENABLE;
ADC_InitStructure.ADC_ContinuousConvMode = ENABLE;
ADC_InitStructure.ADC_ExternalTrigConv = ADC_ExternalTrigConv_None;
ADC_InitStructure.ADC_DataAlign = ADC_DataAlign_Right;
ADC_InitStructure.ADC_NbrOfChannel = 1;
ADC_Init(ADC1, &ADC_InitStructure);
/* ADC1 regular channels configuration */
//ADC_RegularChannelConfig(ADC1, ADC_Channel_4, 1, ADC_SampleTime_239Cycles5);
ADC_Cmd(ADC1, ENABLE);
/* Enable ADC1 reset calibration register */
ADC_ResetCalibration(ADC1);
/* Check the end of ADC1 reset calibration register */
while(ADC_GetResetCalibrationStatus(ADC1));
/* Start ADC1 calibration */
ADC_StartCalibration(ADC1);
/* Check the end of ADC1 calibration */
while(ADC_GetCalibrationStatus(ADC1));
}
u16 get_adc(u8 Channel)
{
u8 i,j;
u16 t[50];
ADC_SoftwareStartConvCmd(ADC1, ENABLE);
ADC_RegularChannelConfig(ADC1, Channel, 1, ADC_SampleTime_239Cycles5);
for(i=0;i<50;i++)
{
t[i]=ADC_GetConversionValue (ADC1);
}
ADC_SoftwareStartConvCmd(ADC1, DISABLE);
for(i=0;i<50-1;i++)
{
for(j=0;j<50-1-i;j++)
{
if(t[j]>t[j+1])
{
t[j]=t[j] ^ t[j+1];
t[j+1]=t[j] ^ t[j+1];
t[j]=t[j] ^ t[j+1];
}
}
}
return (t[24]+t[25])/2;
}
}
adc.h:
#ifndef ADC_H
#define ADC_H
#include "stm32f10x.h"
void adc_init(void);
u16 get_adc(void);
#endif
4.定时器3输出pwm
代码如下:pwm.c:
#include "pwm.h"
void time3_pwm_init(void)
{
TIM_TimeBaseInitTypeDef TIM_TimeBaseStructure;
TIM_OCInitTypeDef TIM_OCInitStructure;
GPIO_InitTypeDef GPIO_InitStructure;
NVIC_InitTypeDef NVIC_InitStructure;
RCC_APB1PeriphClockCmd(RCC_APB1Periph_TIM3, ENABLE);
RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOA, ENABLE);
/* Enable the TIM3 global Interrupt */
NVIC_InitStructure.NVIC_IRQChannel = TIM3_IRQn;
NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = 0;
NVIC_InitStructure.NVIC_IRQChannelSubPriority = 0;
NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE;
NVIC_Init(&NVIC_InitStructure);
GPIO_InitStructure.GPIO_Pin = GPIO_Pin_7 ;
GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF_PP;
GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
GPIO_Init(GPIOA, &GPIO_InitStructure);
/* Time base configuration */
TIM_TimeBaseStructure.TIM_Period = 65535;
TIM_TimeBaseStructure.TIM_Prescaler = 71;
TIM_TimeBaseStructure.TIM_ClockDivision = 0;
TIM_TimeBaseStructure.TIM_CounterMode = TIM_CounterMode_Up;
TIM_TimeBaseInit(TIM3, &TIM_TimeBaseStructure);
/* Output Compare Toggle Mode configuration: Channel1 */
TIM_OCInitStructure.TIM_OCMode = TIM_OCMode_Toggle;
TIM_OCInitStructure.TIM_OutputState = TIM_OutputState_Enable;
TIM_OCInitStructure.TIM_Pulse = 65535;
TIM_OCInitStructure.TIM_OCPolarity = TIM_OCPolarity_Low;
TIM_OC2Init(TIM3, &TIM_OCInitStructure);
/* TIM enable counter */
TIM_Cmd(TIM3, ENABLE);
/* TIM IT enable */
TIM_ITConfig(TIM3, TIM_IT_CC2 , ENABLE);
}
u32 PWM_VAL,PWM_DUTY;
void set_pwm(u32 pwm_val,u32 pwm_duty)
{
PWM_VAL=1000000/pwm_val;
PWM_DUTY= pwm_duty * PWM_VAL /100;
TIM_SetCounter(TIM3,0);
TIM_SetCompare2(TIM3,0);
}
u32 capture;
static u8 ch2_mode=0;
void TIM3_IRQHandler(void)
{
/* TIM3_CH2 toggling with frequency = 366.2 Hz */
if (TIM_GetITStatus(TIM3, TIM_IT_CC2) != RESET)
{
TIM_ClearITPendingBit(TIM3, TIM_IT_CC2);
capture = TIM_GetCapture2(TIM3);
if(ch2_mode)
{
TIM_SetCompare2(TIM3, capture + PWM_VAL);
}
else
{
TIM_SetCompare2(TIM3, capture + PWM_VAL - PWM_VAL);
}
ch2_mode ^=1;
}
}
pwm.h:
#ifndef PWM_H
#define PWM_H
#include "stm32f10x.h"
void time3_pwm_init(void);
void set_pwm(u32 pwm_val,u32 pwm_duty);
#endif
5.定时器2捕获2路pwm频率
代码如下:capture.c:
#include "capture.h"
void time2_capture_init(void)
{
TIM_TimeBaseInitTypeDef TIM_TimeBaseStructure;
NVIC_InitTypeDef NVIC_InitStructure;
GPIO_InitTypeDef GPIO_InitStructure;
TIM_ICInitTypeDef TIM_ICInitStructure;
RCC_APB1PeriphClockCmd(RCC_APB1Periph_TIM2, ENABLE);
/* GPIOA clock enable */
RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOA, ENABLE);
/* Enable the TIM3 global Interrupt */
NVIC_InitStructure.NVIC_IRQChannel = TIM2_IRQn;
NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = 0;
NVIC_InitStructure.NVIC_IRQChannelSubPriority = 0;
NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE;
NVIC_Init(&NVIC_InitStructure);
/* TIM3 channel 2 pin (PA.07) configuration */
GPIO_InitStructure.GPIO_Pin = GPIO_Pin_1 | GPIO_Pin_2;
GPIO_InitStructure.GPIO_Mode = GPIO_Mode_IN_FLOATING;
GPIO_Init(GPIOA, &GPIO_InitStructure);
/* Time base configuration */
TIM_TimeBaseStructure.TIM_Period = 65535;
TIM_TimeBaseStructure.TIM_Prescaler = 71;
TIM_TimeBaseStructure.TIM_ClockDivision = 0;
TIM_TimeBaseStructure.TIM_CounterMode = TIM_CounterMode_Up;
TIM_TimeBaseInit(TIM2, &TIM_TimeBaseStructure);
TIM_ICInitStructure.TIM_Channel = TIM_Channel_2;
TIM_ICInitStructure.TIM_ICPolarity = TIM_ICPolarity_Rising;
TIM_ICInitStructure.TIM_ICSelection = TIM_ICSelection_DirectTI;
TIM_ICInitStructure.TIM_ICPrescaler = TIM_ICPSC_DIV1;
TIM_ICInitStructure.TIM_ICFilter = 0x0;
TIM_ICInit(TIM2, &TIM_ICInitStructure);
TIM_ICInitStructure.TIM_Channel = TIM_Channel_3;
TIM_ICInit(TIM2, &TIM_ICInitStructure);
/* TIM enable counter */
TIM_Cmd(TIM2, ENABLE);
/* Enable the CC2 Interrupt Request */
TIM_ITConfig(TIM2, TIM_IT_CC2 | TIM_IT_CC3, ENABLE);
}
u8 mode=1;
u8 ch2_mode=0,ch3_mode=0;
u32 CH2_VAL,CH2_DUTY,CH3_VAL,CH3_DUTY;
void TIM2_IRQHandler(void)
{
if(TIM_GetITStatus(TIM2, TIM_IT_CC2) == SET)
{
/* Clear TIM3 Capture compare interrupt pending bit */
TIM_ClearITPendingBit(TIM2, TIM_IT_CC2);
if(mode==1)
{
switch(ch2_mode)
{
case 0: CH2_VAL=0;
CH2_DUTY=0;
TIM_SetCounter(TIM2,0);
TIM_OC2PolarityConfig(TIM2,TIM_OCPolarity_Low);
ch2_mode=1;
break;
case 1: CH2_DUTY=TIM_GetCounter(TIM2);
TIM_OC2PolarityConfig(TIM2,TIM_OCPolarity_High);
ch2_mode=2;
break;
case 2: CH2_VAL=TIM_GetCounter(TIM2);
TIM_OC2PolarityConfig(TIM2,TIM_OCPolarity_High);
ch2_mode=3;
break;
default: break;
}
}
else
{
ch2_mode=0;
TIM_OC2PolarityConfig(TIM2,TIM_OCPolarity_High);
}
}
if(TIM_GetITStatus(TIM2, TIM_IT_CC3) == SET)
{
/* Clear TIM3 Capture compare interrupt pending bit */
TIM_ClearITPendingBit(TIM2, TIM_IT_CC3);
if(mode==0)
{
switch(ch3_mode)
{
case 0: CH3_VAL=0;
CH3_DUTY=0;
TIM_SetCounter(TIM2,0);
TIM_OC3PolarityConfig(TIM2,TIM_OCPolarity_Low);
ch3_mode=1;
break;
case 1: CH3_DUTY=TIM_GetCounter(TIM2);
TIM_OC3PolarityConfig(TIM2,TIM_OCPolarity_High);
ch3_mode=2;
break;
case 2: CH3_VAL=TIM_GetCounter(TIM2);
TIM_OC3PolarityConfig(TIM2,TIM_OCPolarity_High);
ch3_mode=3;
break;
default: break;
}
}
else
{
ch3_mode=0;
TIM_OC3PolarityConfig(TIM2,TIM_OCPolarity_High);
}
}
}
capture.h:
#ifndef CAPTURE_H
#define CAPTURE_H
#include "stm32f10x.h"
void time2_capture_init(void);
extern u8 mode;
extern u8 ch2_mode,ch3_mode;
extern u32 CH2_VAL,CH2_DUTY,CH3_VAL,CH3_DUTY;
#endif
三、主函数逻辑设计
stm32f10x_it.c:
#include "stm32f10x_it.h"
extern u32 TimingDelay;
extern u8 key_flag;
extern u8 mode;
void SysTick_Handler(void)
{
static u8 key_num=0;
static u16 time_num=0;
key_num++;
time_num++;
if(key_num==50)
{
key_num=0;
key_flag=1;
}
if(time_num==500)
{
time_num=0;
mode ^=1;
}
TimingDelay--;
}
main.c:
#include "stm32f10x.h"
#include "stdio.h"
#include "adc.h"
#include "lcd.h"
#include "led.h"
#include "key.h"
#include "capture.h"
#include "pwm.h"
u32 TimingDelay = 0;
u8 key_flag;
u8 key_num[4];
u8 key1_flag=1;
void Delay_Ms(u32 nTime);
void key_read(void);
void lcd_show(void);
float rp5,rp6;
u8 buff[20];
u8 vd=1,fd=2;
u8 key4_flag=1;
//Main Body
int main(void)
{
SysTick_Config(SystemCoreClock/1000);
Delay_Ms(200);
STM3210B_LCD_Init();
LCD_Clear(Black);
LCD_SetBackColor(Black);
LCD_SetTextColor(White);
led_init();
key_init();
adc_init();
time2_capture_init();
time3_pwm_init();
while(1)
{
if(key_flag)
{
key_read();
key_flag=0;
}
lcd_show();
}
}
//
void Delay_Ms(u32 nTime)
{
TimingDelay = nTime;
while(TimingDelay != 0);
}
void key_read(void)
{
if(key1==0)
{
key_num[0]++;
if(key_num[0]>15)
{
}
}
else
{
if(key_num[0]>1 && key_num[0]<10)
{
key1_flag ^=1;
if(key1_flag==1)
{
GPIOC->ODR |=(0xff<<8);
GPIOD->ODR |=(1<<2);
GPIOD->ODR &=~(1<<2);
}
}
key_num[0]=0;
}
if(key2==0 && key1_flag==0)
{
key_num[1]++;
if(key_num[1]>15)
{
}
}
else
{
if(key_num[1]>1 && key_num[1]<10)
{
vd++;
if(vd==fd)
{
vd++;
}
if(vd>8)
{
vd=1;
}
}
key_num[1]=0;
}
if(key3==0 && key1_flag==0)
{
key_num[2]++;
if(key_num[2]>15)
{
}
}
else
{
if(key_num[2]>1 && key_num[2]<10)
{
fd++;
if(vd==fd)
{
fd++;
}
if(fd>8)
{
fd=1;
}
}
key_num[2]=0;
}
if(key4==0)
{
key_num[3]++;
if(key_num[3]>15)
{
}
}
else
{
if(key_num[3]>1 && key_num[3]<10)
{
key4_flag ^=1;
}
key_num[3]=0;
}
}
void lcd_show(void)
{
if(key1_flag==1)
{
LCD_DisplayStringLine(Line1," DATA ");
rp5=(float)get_adc(ADC_Channel_4)/0xfff*3.3;
sprintf((char *)buff," V1:%0.1fV ",rp5);
LCD_DisplayStringLine(Line3,buff);
rp6=(float)get_adc(ADC_Channel_5)/0xfff*3.3;
sprintf((char *)buff," V2:%0.1fV ",rp6);
LCD_DisplayStringLine(Line4,buff);
if(rp5>rp6)
{
led_ctrl(vd+7,1);
}
else
{
led_ctrl(vd+7,0);
}
if(ch2_mode==3)
{
if(key4_flag)
{
set_pwm(1000000/CH2_VAL,CH2_DUTY *100 / CH2_VAL);
}
else
{
set_pwm(1000000/CH3_VAL,CH3_DUTY *100 / CH3_VAL);
}
sprintf((char *)buff," F1:%dHz ",1000000/CH2_VAL);
LCD_DisplayStringLine(Line5,buff);
ch2_mode=0;
}
if(ch3_mode==3)
{
if(key4_flag)
{
set_pwm(1000000/CH2_VAL,CH2_DUTY *100 / CH2_VAL);
}
else
{
set_pwm(1000000/CH3_VAL,CH3_DUTY *100 / CH3_VAL);
}
sprintf((char *)buff," F2:%dHz ",1000000/CH3_VAL);
LCD_DisplayStringLine(Line6,buff);
ch3_mode=0;
}
if(1000000/CH2_VAL > 1000000/CH3_VAL)
{
led_ctrl(fd+7,1);
}
else
{
led_ctrl(fd+7,0);
}
}
else
{
LCD_DisplayStringLine(Line1," PARA ");
sprintf((char *)buff," VD:LD%d ",vd);
LCD_DisplayStringLine(Line3,buff);
sprintf((char *)buff," FD:LD%d ",fd);
LCD_DisplayStringLine(Line4,buff);
LCD_DisplayStringLine(Line5," ");
LCD_DisplayStringLine(Line6," ");
}
}
四、 代码测试结果图
①主测试界面:
②设置界面