文章目录
前言
**本程序设计是基于嵌入式开发板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捕获PWM2
代码如下:capture.c:
#include "capture.h"
u8 ch2_mode=0 ;
void time3_capture_init(void)
{
GPIO_InitTypeDef GPIO_InitStructure;
TIM_TimeBaseInitTypeDef TIM_TimeBaseStructure;
TIM_ICInitTypeDef TIM_ICInitStructure;
NVIC_InitTypeDef NVIC_InitStructure;
/* TIM3 clock enable */
RCC_APB1PeriphClockCmd(RCC_APB1Periph_TIM3, ENABLE);
/* GPIOA clock enable */
RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOA | RCC_APB2Periph_AFIO, ENABLE);
/* Enable the TIM3 global Interrupt */
NVIC_InitStructure.NVIC_IRQChannel = TIM3_IRQn;
NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = 0;
NVIC_InitStructure.NVIC_IRQChannelSubPriority = 1;
NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE;
NVIC_Init(&NVIC_InitStructure);
GPIO_InitStructure.GPIO_Pin = GPIO_Pin_7 ;
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(TIM3, &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(TIM3, &TIM_ICInitStructure);
/* TIM enable counter */
TIM_Cmd(TIM3, ENABLE);
/* Enable the CC2 Interrupt Request */
TIM_ITConfig(TIM3, TIM_IT_CC2, ENABLE);
}
u32 ch2_val,ch2_duty;
void TIM3_IRQHandler(void)
{
if(TIM_GetITStatus(TIM3, TIM_IT_CC2) == SET)
{
/* Clear TIM3 Capture compare interrupt pending bit */
TIM_ClearITPendingBit(TIM3, TIM_IT_CC2);
switch(ch2_mode)
{
case 0: ch2_val=0;
ch2_duty=0;
TIM_SetCounter(TIM3,0);
TIM_OC2PolarityConfig(TIM3,TIM_OCPolarity_Low);
ch2_mode=1;
break;
case 1: ch2_duty=TIM_GetCounter(TIM3);
TIM_OC2PolarityConfig(TIM3,TIM_OCPolarity_High);
ch2_mode=2;
break;
case 2: ch2_val=TIM_GetCounter(TIM3);
TIM_OC2PolarityConfig(TIM3,TIM_OCPolarity_High);
ch2_mode=3;
break;
default: break;
}
}
}
capture.h:
#ifndef CAPTURE_H
#define CAPTURE_H
#include "stm32f10x.h"
extern u8 ch2_mode;
extern u32 ch2_val,ch2_duty;
void time3_capture_init(void);
#endif
5.ds18b20测量温度
代码如下:ds18b20.c:
#include "stm32f10x.h"
#include "ds18b20.h"
#define delay_us(X) delay((X)*72/5)
void delay(unsigned int n)
{
while(n--);
}
void ds18b20_init_x(void)
{
GPIO_InitTypeDef GPIO_InitStructure;
/* Enable clock */
RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOA , ENABLE);
/* Configure Ports */
GPIO_InitStructure.GPIO_Pin = GPIO_Pin_6;
GPIO_InitStructure.GPIO_Mode = GPIO_Mode_IPU;
GPIO_InitStructure.GPIO_Speed = GPIO_Speed_2MHz;
GPIO_Init(GPIOA, &GPIO_InitStructure);
}
//
void mode_input1(void )
{
GPIO_InitTypeDef GPIO_InitStructure;
GPIO_InitStructure.GPIO_Pin = GPIO_Pin_6;
GPIO_InitStructure.GPIO_Mode = GPIO_Mode_IPU;
GPIO_InitStructure.GPIO_Speed = GPIO_Speed_2MHz;
GPIO_Init(GPIOA, &GPIO_InitStructure);
}
void mode_output1(void )
{
GPIO_InitTypeDef GPIO_InitStructure;
GPIO_InitStructure.GPIO_Pin = GPIO_Pin_6;
GPIO_InitStructure.GPIO_Mode = GPIO_Mode_Out_PP;
GPIO_InitStructure.GPIO_Speed = GPIO_Speed_2MHz;
GPIO_Init(GPIOA, &GPIO_InitStructure);
}
//
uint8_t ow_reset(void)
{
uint8_t err;
OW_DIR_OUT(); // pull OW-Pin low for 480us
OW_OUT_LOW(); // disable internal pull-up (maybe on from parasite)
delay_us(400); //about 480us
// set Pin as input - wait for clients to pull low
OW_DIR_IN(); // input
delay_us(66);
err = OW_GET_IN(); // no presence detect
// nobody pulled to low, still high
// after a delay the clients should release the line
// and input-pin gets back to high due to pull-up-resistor
delay_us(480-66);
if( OW_GET_IN() == 0 ) // short circuit
err = 1;
return err;
}
uint8_t ow_bit_io( uint8_t b )
{
OW_DIR_OUT(); // drive bus low
OW_OUT_LOW();
delay_us(1); // Recovery-Time wuffwuff was 1
if ( b ) OW_DIR_IN(); // if bit is 1 set bus high (by ext. pull-up)
#define OW_CONF_DELAYOFFSET 5
delay_us(15-1-OW_CONF_DELAYOFFSET);
if( OW_GET_IN() == 0 ) b = 0; // sample at end of read-timeslot
delay_us(60-15);
OW_DIR_IN();
return b;
}
uint8_t ow_byte_wr( uint8_t b )
{
uint8_t i = 8, j;
do
{
j = ow_bit_io( b & 1 );
b >>= 1;
if( j ) b |= 0x80;
}
while( --i );
return b;
}
//
uint8_t ow_byte_rd( void )
{
return ow_byte_wr( 0xFF );
}
float ds18b20_read(void)
{
u8 i;
s16 x;
u8 val[2];
u8 s;
float temp;
ow_reset();
ow_byte_wr(OW_SKIP_ROM);
ow_byte_wr(DS18B20_CONVERT);
//delay_us(750000);
ow_reset();
ow_byte_wr(OW_SKIP_ROM);
ow_byte_wr(DS18B20_READ);
for(i=0;i<2;i++)
{
val[i]=ow_byte_rd();
}
if(val[1]>7)
{
val[0]=~val[0];
val[1]=~val[1];
s=1;
}
else
{
s=0;
}
x=val[1];
x=x<<8;
x=x | val[0];
//x=x&0x7ff;
temp=(float)x/16.0;
if(s)
{
return -temp;
}
else
{
return temp;
}
}
ds18b20.h:
#ifndef __DS18B20_H
#define __DS18B20_H
#include "stm32f10x.h"
#define OW_DIR_OUT() mode_output1()
#define OW_DIR_IN() mode_input1()
#define OW_OUT_LOW() (GPIO_ResetBits(GPIOA,GPIO_Pin_6))
#define OW_GET_IN() (GPIO_ReadInputDataBit(GPIOA,GPIO_Pin_6))
#define OW_SKIP_ROM 0xCC
#define DS18B20_CONVERT 0x44
#define DS18B20_READ 0xBE
void ds18b20_init_x(void);
float ds18b20_read(void);
#endif
6.i2c对eeprom的存取
i2c.c
/*
程序说明: CT117E嵌入式竞赛板GPIO模拟I2C总线驱动程序
软件环境: Keil uVision 4.10
硬件环境: CT117E嵌入式竞赛板
日 期: 2011-8-9
*/
#include "stm32f10x.h"
#include "i2c.h"
/** I2C 总线接口 */
#define I2C_PORT GPIOB
#define SDA_Pin GPIO_Pin_7
#define SCL_Pin GPIO_Pin_6
#define FAILURE 0
#define SUCCESS 1
//配置SDA信号线为输入模式
void SDA_Input_Mode()
{
GPIO_InitTypeDef GPIO_InitStructure;
GPIO_InitStructure.GPIO_Pin = SDA_Pin;
GPIO_InitStructure.GPIO_Speed = GPIO_Speed_2MHz;
GPIO_InitStructure.GPIO_Mode = GPIO_Mode_IPD;
GPIO_Init(I2C_PORT, &GPIO_InitStructure);
}
//配置SDA信号线为输出模式
void SDA_Output_Mode()
{
GPIO_InitTypeDef GPIO_InitStructure;
GPIO_InitStructure.GPIO_Pin = SDA_Pin;
GPIO_InitStructure.GPIO_Speed = GPIO_Speed_2MHz;
GPIO_InitStructure.GPIO_Mode = GPIO_Mode_Out_PP;
GPIO_Init(I2C_PORT, &GPIO_InitStructure);
}
//
void SDA_Output( uint16_t val )
{
if ( val ) {
GPIO_SetBits(I2C_PORT,SDA_Pin);
} else {
GPIO_ResetBits(I2C_PORT,SDA_Pin);
}
}
//
void SCL_Output( uint16_t val )
{
if ( val ) {
GPIO_SetBits(I2C_PORT,SCL_Pin);
} else {
GPIO_ResetBits(I2C_PORT,SCL_Pin);
}
}
//
uint8_t SDA_Input()
{
return GPIO_ReadInputDataBit( I2C_PORT, SDA_Pin);
}
//延时程序
void delay1(unsigned int n)
{
unsigned int i;
for ( i=0;i<n;++i);
}
//I2C总线启动
void I2CStart(void)
{
SDA_Output(1);delay1(500);
SCL_Output(1);delay1(500);
SDA_Output(0);delay1(500);
SCL_Output(0);delay1(500);
}
//I2C总线停止
void I2CStop(void)
{
SCL_Output(0); delay1(500);
SDA_Output(0); delay1(500);
SCL_Output(1); delay1(500);
SDA_Output(1); delay1(500);
}
//等待应答
unsigned char I2CWaitAck(void)
{
unsigned short cErrTime = 5;
SDA_Input_Mode();
delay1(500);
SCL_Output(1);delay1(500);
while(SDA_Input())
{
cErrTime--;
delay1(500);
if (0 == cErrTime)
{
SDA_Output_Mode();
I2CStop();
return FAILURE;
}
}
SDA_Output_Mode();
SCL_Output(0);delay1(500);
return SUCCESS;
}
//发送应答位
void I2CSendAck(void)
{
SDA_Output(0);delay1(500);
delay1(500);
SCL_Output(1); delay1(500);
SCL_Output(0); delay1(500);
}
//
void I2CSendNotAck(void)
{
SDA_Output(1);
delay1(500);
SCL_Output(1); delay1(500);
SCL_Output(0); delay1(500);
}
//通过I2C总线发送一个字节数据
void I2CSendByte(unsigned char cSendByte)
{
unsigned char i = 8;
while (i--)
{
SCL_Output(0);delay1(500);
SDA_Output(cSendByte & 0x80); delay1(500);
cSendByte += cSendByte;
delay1(500);
SCL_Output(1);delay1(500);
}
SCL_Output(0);delay1(500);
}
//从I2C总线接收一个字节数据
unsigned char I2CReceiveByte(void)
{
unsigned char i = 8;
unsigned char cR_Byte = 0;
SDA_Input_Mode();
while (i--)
{
cR_Byte += cR_Byte;
SCL_Output(0);delay1(500);
delay1(500);
SCL_Output(1);delay1(500);
cR_Byte |= SDA_Input();
}
SCL_Output(0);delay1(500);
SDA_Output_Mode();
return cR_Byte;
}
//I2C总线初始化
void i2c_init()
{
GPIO_InitTypeDef GPIO_InitStructure;
RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOB, ENABLE);
GPIO_InitStructure.GPIO_Pin = SDA_Pin | SCL_Pin;
GPIO_InitStructure.GPIO_Speed = GPIO_Speed_2MHz;
GPIO_InitStructure.GPIO_Mode = GPIO_Mode_Out_PP; // **
GPIO_Init(I2C_PORT, &GPIO_InitStructure);
}
void i2c_write(u8 addr,u8 data)
{
I2CStart();
I2CSendByte(0xa0);
I2CWaitAck();
I2CSendByte(addr);
I2CWaitAck();
I2CSendByte(data);
I2CWaitAck();
I2CStop();
}
u8 i2c_read(u8 addr)
{
u8 t;
I2CStart();
I2CSendByte(0xa0);
I2CWaitAck();
I2CSendByte(addr);
I2CWaitAck();
I2CStart();
I2CSendByte(0xa1);
I2CWaitAck();
t=I2CReceiveByte();
I2CWaitAck();
I2CStop();
return t;
}
i2c.h
#ifndef __I2C_H__
#define __I2C_H__
void i2c_init(void);
void delay1(unsigned int n);
void I2CStart(void);
void I2CStop(void);
void I2CSendAck(void);
void I2CSendNotAck(void);
unsigned char I2CWaitAck(void);
void I2CSendByte(unsigned char cSendByte);
unsigned char I2CReceiveByte(void);
void i2c_write(u8 addr,u8 data);
u8 i2c_read(u8 addr);
#endif
7.数码管显示
seg.c
#include "seg.h"
u8 table[17] = { 0x3f,0x06,0x5b,0x4f, 0x66,0x6d,0x7d,0x07,0x7f,0x6f,0x77,0x7c, 0x39,0x4f,0x79,0x78,0x00};
void seg_init(void)
{
GPIO_InitTypeDef GPIO_InitStructure;
/* GPIOD Periph clock enable */
RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOA, ENABLE);
/* Configure PD0 and PD2 in output pushpull mode */
GPIO_InitStructure.GPIO_Pin = GPIO_Pin_2 | GPIO_Pin_1 | GPIO_Pin_3;
GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
GPIO_InitStructure.GPIO_Mode = GPIO_Mode_Out_PP;
GPIO_Init(GPIOA, &GPIO_InitStructure);
}
void seg_show(u8 bit1,u8 bit2, u8 bit3)
{
u8 bit;
u8 i;
RCK_L; // 锁住数据,防止串口的干扰,使得 RCK为高电平, 造成数码管显示错误
bit=table[bit3];
for(i=0;i<8;i++)
{
if(bit&0x80)
{
SER_H;
}
else
{
SER_L;
}
SCK_H;
bit=bit<<1;
SCK_L;
}
bit=table[bit2];
for(i=0;i<8;i++)
{
if(bit&0x80)
{
SER_H;
}
else
{
SER_L;
}
SCK_H;
bit=bit<<1;
SCK_L;
}
bit=table[bit1];
for(i=0;i<8;i++)
{
if(bit&0x80)
{
SER_H;
}
else
{
SER_L;
}
SCK_H;
bit=bit<<1;
SCK_L;
}
RCK_H; //等到所有数据都移位成功后,再一次性将移位寄存器的数据存放到数据寄存器进行数码管显示
}
seg.h
#ifndef SEG_H
#define SEG_H
#include "stm32f10x.h"
#define SER_H GPIO_SetBits(GPIOA,GPIO_Pin_1)
#define SER_L GPIO_ResetBits(GPIOA,GPIO_Pin_1)
#define RCK_H GPIO_SetBits(GPIOA,GPIO_Pin_2)
#define RCK_L GPIO_ResetBits(GPIOA,GPIO_Pin_2)
#define SCK_H GPIO_SetBits(GPIOA,GPIO_Pin_3)
#define SCK_L GPIO_ResetBits(GPIOA,GPIO_Pin_3)
void seg_init(void);
void seg_show(u8 bit1,u8 bit2, u8 bit3);
#endif
8.串口
usart.c
#include "usart.h"
void usart_init(void)
{
NVIC_InitTypeDef NVIC_InitStructure;
USART_InitTypeDef USART_InitStructure;
GPIO_InitTypeDef GPIO_InitStructure;
RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOA| RCC_APB2Periph_AFIO, ENABLE);
RCC_APB1PeriphClockCmd(RCC_APB1Periph_USART2, ENABLE);
/* Configure USARTy Rx as input floating */
GPIO_InitStructure.GPIO_Pin = GPIO_Pin_3;
GPIO_InitStructure.GPIO_Mode = GPIO_Mode_IN_FLOATING;
GPIO_Init(GPIOA, &GPIO_InitStructure);
/* Configure USARTy Tx as alternate function push-pull */
GPIO_InitStructure.GPIO_Pin = GPIO_Pin_2;
GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF_PP;
GPIO_Init(GPIOA, &GPIO_InitStructure);
USART_InitStructure.USART_BaudRate = 9600;
USART_InitStructure.USART_WordLength = USART_WordLength_8b;
USART_InitStructure.USART_StopBits = USART_StopBits_1;
USART_InitStructure.USART_Parity = USART_Parity_No;
USART_InitStructure.USART_HardwareFlowControl = USART_HardwareFlowControl_None;
USART_InitStructure.USART_Mode = USART_Mode_Rx| USART_Mode_Tx;
/* Configure USARTz */
USART_Init(USART2, &USART_InitStructure);
/* Enable USARTz Receive and Transmit interrupts */
USART_ITConfig(USART2, USART_IT_RXNE, ENABLE);
/* Enable the USARTz */
USART_Cmd(USART2, ENABLE);
NVIC_PriorityGroupConfig(NVIC_PriorityGroup_0);
/* Enable the USARTz Interrupt */
NVIC_InitStructure.NVIC_IRQChannel = USART2_IRQn;
NVIC_InitStructure.NVIC_IRQChannelSubPriority = 1;
NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE;
NVIC_Init(&NVIC_InitStructure);
}
void sent_data(char *s)
{
do
{
USART_SendData(USART2,*s++);
while(USART_GetFlagStatus(USART2,USART_FLAG_TXE)==0);
}while(*s);
}
u8 usart_buff[8];
u8 count=0;
u8 data, para,erro;
void USART2_IRQHandler(void)
{
if(USART_GetITStatus(USART2, USART_IT_RXNE) != RESET)
{
usart_buff[count]=USART_ReceiveData(USART2);
if(usart_buff[0]=='S' && usart_buff[1]=='T' )
{
data=1;
}
if(usart_buff[0]=='P' && usart_buff[1]=='A' && usart_buff[2]=='R' && usart_buff[3]=='A' )
{
para=1;
}
else
{
erro=1;
}
count++;
}
}
usart.h
#ifndef USART_H
#define USART_H
#include "stm32f10x.h"
void usart_init(void);
void sent_data(char *s);
extern u8 data, para,count,erro;
extern u8 usart_buff[8];
#endif
三、主函数逻辑设计
stm32f10x_it.c:
#include "stm32f10x_it.h"
#include "usart.h"
extern u32 TimingDelay;
extern u8 key_flag;
extern u8 adc_flag;
extern u8 seg_flag;
extern u8 led_flag;
extern u8 usart_flag;
void SysTick_Handler(void)
{
static u8 key_num=0;
static u16 adc_num=0;
static u16 seg_num=0;
static u16 usart_num=0;
static u8 led_num=0;
key_num++;
if(key_num==50)
{
key_flag=1;
key_num=0;
}
adc_num++;
if(adc_num==300)
{
adc_flag=1;
adc_num=0;
}
seg_num++;
if(seg_num==2000)
{
seg_flag ^=1;
seg_num=0;
}
usart_num++;
if(usart_num==1000)
{
usart_flag ^=1;
usart_num=0;
}
led_num++;
if(led_num==200)
{
led_flag ^=1;
led_num=0;
}
TimingDelay--;
}
这里串口和数码管的引脚冲突,需要分时复用。
main.c:
#include "stm32f10x.h"
#include "stdio.h"
#include "lcd.h"
#include "led.h"
#include "key.h"
#include "adc.h"
#include "capture.h"
#include "ds18b20.h"
#include "seg.h"
#include "i2c.h"
#include "usart.h"
u32 TimingDelay = 0;
u8 key_flag; //按键消抖标志,每50ms刷新一次
u8 adc_flag; //adc收集刷新标志300ms
u8 key1_num; //按键按下的递增值,用于判断长按和短按
u8 key2_num;
u8 key3_num;
u8 key4_num;
u16 adc_val; //存放16位的adc值
u8 key1_flag=1; //按键1按下的标志
u8 buff[20]; //存放拷贝数据缓冲区
u8 led_flag; //led灯的刷新标志,200ms
u8 usart_flag; //串口的刷新标志位,1000ms
float temp; //存放ds18b20的温度值
float v[2]; //存放两路ADC电压的值
u8 t=30; //存放设置参数T的值
u8 x=1; //存放AO1,AO2的值
u8 x_temp,t_temp; //用于存放之前的下,t,x的值,用来判断数据是否被更新
u16 n=0; //存放设置的次数
u8 i; //用于for循环
u8 seg_flag; //数码管的刷新标志位,2000ms
u8 key2_flag=1; //按键2按下的标志位
void Delay_Ms(u32 nTime);
void key_read(void);
void lcd_show(void);
void seg_fun(void); //数码管处理函数
void usart_fun(void); //串口接收后的处理和函数
int main(void)
{
SysTick_Config(SystemCoreClock/1000);
Delay_Ms(200);
STM3210B_LCD_Init();
LCD_Clear(Blue);
LCD_SetBackColor(Blue);
LCD_SetTextColor(Black);
led_init();
key_init();
adc_init();
time3_capture_init();
ds18b20_init_x();
// seg_init();
i2c_init();
// usart_init();
//sent_data("123\n\r");
if(i2c_read(0x20)!=58)
{
led_ctrl(15,1);
i2c_write(0x20,58);
Delay_Ms(5);
i2c_write(0x25,n);
Delay_Ms(5);
}
n=i2c_read(0x25);
Delay_Ms(5);
while(1)
{
if(key_flag)
{
key_read();
key_flag=0;
}
if(temp>t)
{
led_ctrl(15,led_flag);
}
else
{
led_ctrl(15,0);
}
if(v[x-1]>((float)ch2_duty/ch2_val)*3.3 && usart_flag==1)
{
led_ctrl(8,1);
sprintf((char *)buff,"$%0.2f\r\n",temp);
sent_data((char *)buff);
usart_flag=0;
}
else
{
led_ctrl(8,0);
}
lcd_show();
usart_fun();
Delay_Ms(5);
seg_fun();
}
}
void Delay_Ms(u32 nTime)
{
TimingDelay = nTime;
while(TimingDelay != 0);
}
void key_read(void)
{
if(key1==0)
{
key1_num++;
if(key1_num>15)
{
}
}
else
{
if(key1_num>1 && key1_num<8)
{
key1_flag ^= 1;
if(key1_flag==0)
{
x_temp=x;
t_temp=t;
}
else
{
if(x_temp!=x || t_temp!=t)
{
n++;
i2c_write(0x25,n);
Delay_Ms(5);
}
}
}
key1_num=0;
}
//
if(key2==0 && key1_flag==0)
{
key2_num++;
if(key2_num>15)
{
}
}
else
{
if(key2_num>1 && key2_num<8)
{
key2_flag ^=1;
}
key2_num=0;
}
//
if(key3==0 && key1_flag==0 )
{
key3_num++;
if(key3_num>15)
{
if(key2_flag==1)
{
t++;
if(t>40)
{
t=40;
}
}
}
}
else
{
if(key3_num>1 && key3_num<8)
{
if(key2_flag==1)
{
t++;
if(t>40)
{
t=40;
}
}
else
{
if(x==1)
{
x=2;
}
else
{
x=1;
}
}
}
key3_num=0;
}
//
if(key4==0 && key1_flag==0)
{
key4_num++;
if(key4_num>15)
{
if(key2_flag==1)
{
t--;
if(t<20)
{
t=20;
}
}
}
}
else
{
if(key4_num>1 && key4_num<8)
{
if(key2_flag==1)
{
t--;
if(t<20)
{
t=20;
}
}
else
{
if(x==1)
{
x=2;
}
else
{
x=1;
}
}
}
key4_num=0;
}
}
void lcd_show(void)
{
if(key1_flag)
{
LCD_DisplayStringLine(Line1," Main ");
if(adc_flag)
{
adc_val=get_adc(ADC_Channel_4);
v[0]=(float)adc_val*3.3/0xfff;
sprintf((char *)buff," AO1:%0.2fV ",v[0]);
LCD_DisplayStringLine(Line3,buff);
adc_val=get_adc(ADC_Channel_5);
v[1]=(float)adc_val*3.3/0xfff;
sprintf((char *)buff," AO2:%0.2fV ",v[1]);
LCD_DisplayStringLine(Line4,buff);
adc_flag=0;
}
if(ch2_mode==3)
{
sprintf((char *)buff," PWM2:%d%% ",ch2_duty*100/ch2_val);
LCD_DisplayStringLine(Line5,buff);
ch2_mode=0;
}
temp=ds18b20_read();
sprintf((char *)buff," Temp:%0.2fC ",temp);
LCD_DisplayStringLine(Line6,buff);
sprintf((char *)buff," N:%d ",n);
LCD_DisplayStringLine(Line7,buff);
}
else
{
LCD_SetBackColor(Blue);
LCD_DisplayStringLine(Line1," Para ");
if(key2_flag==1)
{
LCD_SetBackColor(Yellow);
}
else
{
LCD_SetBackColor(Blue);
}
sprintf((char *)buff," T:%d ",t);
LCD_DisplayStringLine(Line3,buff);
if(key2_flag==0)
{
LCD_SetBackColor(Yellow);
}
else
{
LCD_SetBackColor(Blue);
}
sprintf((char *)buff," X:AO%d ",x);
LCD_DisplayStringLine(Line4,buff);
LCD_SetBackColor(Blue);
LCD_DisplayStringLine(Line5," ");
LCD_DisplayStringLine(Line6," ");
LCD_DisplayStringLine(Line7," ");
}
}
void seg_fun(void)
{
seg_init();
if(seg_flag)
{
seg_show(12,t/10,t%10);
}
else
{
seg_show(10,0,x);
}
usart_init();
}
void usart_fun(void)
{
if(data)
{
sprintf((char *)buff,"$%0.2f\r\n",temp);
sent_data((char *)buff);
data=0;
count=0;
for(i=0;i<8;i++)
{
usart_buff[i]=0;
}
}
if(para)
{
para=0;
count=0;
sprintf((char *)buff,"#%d,AO%d\r\n",t,x);
sent_data((char *)buff);
for(i=0;i<8;i++)
{
usart_buff[i]=0;
}
}
if(erro)
{
count=0;
for(i=0;i<8;i++)
{
usart_buff[i]=0;
}
erro=0;
}
seg_fun();
}
四、 代码测试结果图
①主测试界面:
②设置界面