|||
代码内容如下:
MAIN.C文件
#include "main.h"
#include "stm32f10x.h"
#include "oled.h"
#include "delay.h"
u8 uart_comp = 0;
unsigned long G_un32TestCont=0;
unsigned long IR_Code = 0;
unsigned long IR_Key = 0xff;
unsigned char un8VoiceCount = 0;
unsigned char Motor_Flag = 0;
/*******************************************************************************
* Function Name : main
* Description : 程序入口函数
* Input : None
* Output : None
* Return : None
* Attention :
*******************************************************************************/
/*******************************
*电机驱动模块连线说明: *OLED模块连线说明: *语音模块连线说明: *遥控模块连线说明:
*1--IN1 <----->PA1 *1--SDA <----->PB7 *1--GND <----->GND *1--IN <----->PB0
*2--IN2 <----->PA2 *2--SCL <----->PB6 *2--P_E <----->PA7 *2--GND <----->GND
*3--IN3 <----->PA3 *3--GND <----->GND *3--VCC <----->3.3V *3--VCC <----->3.3V
*4--IN4 <----->PA4 *4--VCC <----->3.3V
*5--GND <----->GND
*6--VCC <----->3.3V
************************************/
int main(void)
{
delay_init(72); //延时初始化函数
RCC_Configuration();
MOTOR1_OFF; //左轮
MOTOR2_OFF;
MOTOR3_OFF; //右轮
MOTOR4_OFF;
SPI1_GPIO_Config();
ALL_GPIO_Config();
OLED_Initial();
USART_Configuration1();
TIM_InitConfigFunc();
NVIC_Configuration();
LED_OFF;
while(1)
{
if(Motor_Flag == 0)
{
LCD_CLS();
LCD_P8x16Str(3,2,"Very Good Boys!");
}
else if(Motor_Flag == 1)
{
LCD_CLS();
LCD_P8x16Str(20,2,"Forward!");
}
else if(Motor_Flag == 7)
{
LCD_CLS();LCD_P8x16Str(20,2,"Backward!");
}
else if(Motor_Flag == 5)
{
LCD_CLS();LCD_P8x16Str(20,2,"Turn Left!");
}
else if(Motor_Flag == 6)
{
LCD_CLS();LCD_P8x16Str(20,2,"Turn Right!");
}
else if(Motor_Flag == 9)
{
LCD_CLS();LCD_P8x16Str(20,2,"Stop!");
}
sleep(500);
LED_ON;
sleep(500);
LED_OFF;
un8VoiceCount++;
if(un8VoiceCount >= 10)
{
VOICE_ON;
sleep(500);
un8VoiceCount = 0;
VOICE_OFF;
}
}
}
KEY_DRIVER.C文件
/**********************************************************************************
** 函数名称:TIM2_IRQHandler
** 输入参数:无
** 输出参数:无
** 功能描述:定时两帧数据之间的间隔,并调用ID辨别和数据校验函数。
******************************************************************************/
unsigned char un8ModeCont = 0;
void TIM2_IRQHandler(void) //TIM2中断
{
if (TIM_GetITStatus(TIM2, TIM_IT_Update) != RESET)
{
TIM_ClearITPendingBit(TIM2, TIM_IT_Update);
if(Motor_Flag == 2)
{
un8ModeCont++;
if(un8ModeCont <= 3)
{
LCD_CLS();
LCD_P8x16Str(20,2,"Forward!");
Motor_Forward();
}
else if(un8ModeCont == 4)
{
un8ModeCont = 0;
Motor_Stop();
}
}
else if(Motor_Flag == 8)
{
un8ModeCont++;
if(un8ModeCont <= 3)
{
LCD_CLS();
LCD_P8x16Str(20,2,"Backward!");
Motor_Backward();
}
else if(un8ModeCont == 4)
{
un8ModeCont = 0;
Motor_Stop();
}
}
else if(Motor_Flag == 4)
{
un8ModeCont++;
if(un8ModeCont <= 3)
{
LCD_CLS();
LCD_P8x16Str(20,2,"Turn Left!");
Motor_Left();
}
else if(un8ModeCont == 4)
{
un8ModeCont = 0;
Motor_Stop();
}
}
else if(Motor_Flag == 6)
{
un8ModeCont++;
if(un8ModeCont <= 3)
{
LCD_CLS();
LCD_P8x16Str(20,2,"Turn Right!");
Motor_Right();
}
else if(un8ModeCont == 4)
{
un8ModeCont = 0;
Motor_Stop();
}
}
else if(Motor_Flag == 5)
{
Motor_Stop();LCD_CLS();LCD_P8x16Str(20,2,"Stop!");
Motor_Flag = 0;un8ModeCont = 0;
}
}
}
/********************************************************************
** 函数名称: TIM3_IRQHandler()
** 输入参数:无
** 输出参数:无
** 函数功能: 延时倒计时,并调用语音提示函数。 250MS进一次中断
*********************************************************************/
void TIM3_IRQHandler(void) //TIM3中断
{
u16 IR_Pluse;
if(TIM_GetITStatus(TIM3, TIM_IT_CC3) != RESET)//判断是否发生捕获事件
{
TIM_ClearITPendingBit(TIM3, TIM_IT_CC3);
TIM3->CNT=0;
if(IR_Key == 0xff)
{
IR_Code = IR_Code<<1;
IR_Pluse = TIM_GetCapture3(TIM3);
if((IR_Pluse<1300)&&(IR_Pluse>800))
IR_Code = IR_Code&0xFFFE;
if((IR_Pluse<2500)&&(IR_Pluse>1300))
IR_Code = IR_Code|0x0001;
switch(IR_Code)
{
case _KEY_2:
Motor_Flag = 2;
IR_Key = 0xff; break;
case _KEY_8:
Motor_Flag = 8;
IR_Key = 0xff; break;
case _KEY_4:
Motor_Flag = 4;
IR_Key = 0xff; break;
case _KEY_6:
Motor_Flag = 6;
IR_Key = 0xff; break;
case _KEY_5:
Motor_Flag = 5;
IR_Key = 0xff; break;
case _KEY_6:
Motor_Flag = 5;
IR_Key = 0xff; break;
case _KEY_8:
Motor_Flag = 5;
IR_Key = 0xff; break;
case _KEY_9:
Motor_Flag = 5;
IR_Key = 0xff; break;
}
}
}
}
SPI.C文件
#include "SPI.h"
vu8 SPI1_TX_Buff[1] = { 0 }; //SPI2 发送缓存
vu8 SPI1_RX_Buff[1] = { 0 }; //SPI2 接收缓存
/*******************************************************************************
* Function Name : SPI2_GPIO_Config
* Description : SPI2 Configures the different GPIO ports.
* Input : None
* Output : None
* Return : None
* Attention :
*******************************************************************************/
void SPI1_GPIO_Config(void)
{
GPIO_InitTypeDef GPIO_InitStructure;
/* Configure SPI2 pins: SPI2_SCK(PA.4), SPI2_MISO(PA.5) and SPI2_MOSI(PA.6)*/
GPIO_InitStructure.GPIO_Pin = GPIO_Pin_5 | GPIO_Pin_6 | GPIO_Pin_7;
GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF_PP;
GPIO_Init(GPIOA, &GPIO_InitStructure);
/* Configure SPI2 pins: SPI2_NSS(PA.4) -------------*/
GPIO_InitStructure.GPIO_Pin = GPIO_Pin_4;
GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
GPIO_InitStructure.GPIO_Mode = GPIO_Mode_Out_PP;
GPIO_Init(GPIOA, &GPIO_InitStructure);
SPI_FLASH_CS_HIGH();
SPI1_Configuration();
}
/*******************************************************************************
* Function Name : SPI2_Configuration
* Description : SPI2 寄存器配置, SPI2配置为低速,即Fsck=Fcpu/256
* Input : None
* Output : None
* Return : None
* Attention :
*******************************************************************************/
void SPI1_Configuration(void)
{
SPI_InitTypeDef SPI_InitStructure;
SPI_I2S_DeInit(SPI1);
SPI_InitStructure.SPI_Direction = SPI_Direction_2Lines_FullDuplex; //两线全双工
SPI_InitStructure.SPI_Mode = SPI_Mode_Master;
SPI_InitStructure.SPI_DataSize = SPI_DataSize_8b;
SPI_InitStructure.SPI_CPOL = SPI_CPOL_Low; //CPOL时钟极性:0空闲时SCK保持低电平;
SPI_InitStructure.SPI_CPHA = SPI_CPHA_1Edge; //CPHA时钟相位:
SPI_InitStructure.SPI_NSS = SPI_NSS_Soft; //软件管理NSS
SPI_InitStructure.SPI_BaudRatePrescaler = SPI_BaudRatePrescaler_2;//波特率
SPI_InitStructure.SPI_FirstBit = SPI_FirstBit_MSB; //高位在前
SPI_InitStructure.SPI_CRCPolynomial = 7; //CRC校验
SPI_Init(SPI1, &SPI_InitStructure);
SPI_Cmd(SPI1, ENABLE);
}
/*******************************************************************************
* Function Name : SPI2_Configuration
* Description : SPI2 寄存器配置, SPI2配置为低速,即Fsck=Fcpu/256
* Input : None
* Output : None
* Return : None
* Attention :
*******************************************************************************/
void Test_Functiong(void)
{
u8 uart_buf1[4];
G_un32TestCont++;
if(G_un32TestCont%10 == 0)
{
uart_buf1[0] =0x50;
uart_buf1[1] =0x56;
uart_buf1[2] =0x2f;
uart_buf1[3] =0x4f;
uart_Send(&uart_buf1[0],4);
}
sleep(200);
}
MOTOR.C文件
#include "MOTOR.h"
/*****************************************************************************
** 函数名称:delay_init
** 输入参数:SYSCLK:系统时钟 单位:MHZ
** 输出参数:无
** 功能描述:初始化延迟函数,SYSCLK = 24表示系统时钟为24MHZ,F100C8系统最大时钟为24MHZ。
******************************************************************************/
void delay_init(u8 SYSCLK)
{
//选择外部时钟 HCLK/8 SYSTICK的时钟固定为HCLK时钟的1/8
SysTick_CLKSourceConfig(SysTick_CLKSource_HCLK_Div8);
fac_us=SYSCLK/8;
fac_ms=(u16)fac_us*1000;
}
/*********************************************************************************
** 函数名称:delay_ms
** 输入参数:nms:延时时间,ms级。SysTick->LOAD为24位寄存器,所以,最大延时为:
** nms<=0xffffff*8*1000/SYSCLK; SYSCLK单位为Hz,nms单位为ms
** 输出参数:无
** 功能描述:毫秒延时函数。注意:对24M条件下,nms<=5592 。
**********************************************************************************/
void delay_ms(u16 nms)
{
u32 temp;
SysTick->LOAD=(u32)nms*fac_ms; //时间加载(SysTick->LOAD为24bit)
SysTick->VAL =0x00; //清空计数器
SysTick->CTRL=0x01 ; //开始倒数
do
{
temp=SysTick->CTRL;
}
while(temp&0x01&&!(temp&(1<<16))); //等待时间到达
SysTick->CTRL=0x00; //关闭计数器
SysTick->VAL =0X00; //清空计数器
}
/*********************************************************************************
** 函数名称:delay_us
** 输入参数:nus:延时时间,us级。SysTick->LOAD为24位寄存器,所以,最大延时为:
** nus<=0xffffff*8/SYSCLK; SYSCLK单位为MHz,nus单位为us
** 输出参数:无
** 功能描述:毫秒延时函数。注意:对24M条件下,nms<=5592405 。
***********************************************************************************/
void delay_us(u32 nus)
{
u32 temp;
SysTick->LOAD=nus*fac_us; //时间加载
SysTick->VAL=0x00; //清空计数器
SysTick->CTRL=0x01 ; //开始倒数
do
{
temp=SysTick->CTRL;
}
while(temp&0x01&&!(temp&(1<<16))); //等待时间到达
SysTick->CTRL=0x00; //关闭计数器
SysTick->VAL =0X00; //清空计数器
}
/*************************************************************************
** 函数名称:delay_us
** 输入参数:nus:延时时间,us级。SysTick->LOAD为24位寄存器,所以,最大延时为:
** nus<=0xffffff*8/SYSCLK; SYSCLK单位为MHz,nus单位为us
** 输出参数:无
** 功能描述:毫秒延时函数。注意:对24M条件下,nms<=5592405 。
***********************************************************************/
unsigned char Led_Count = 0;
unsigned char Key_Down_** = 0;
void Body_Infrared_Sensor(void)
{
unsigned char KeyValue1 = 0;
unsigned char KeyValue2 = 0;
KeyValue1= GPIO_ReadInputDataBit(GPIOB,GPIO_Pin_4);
delay_ms(10);
KeyValue2= GPIO_ReadInputDataBit(GPIOB,GPIO_Pin_4);
if(KeyValue1 == KeyValue2)
{
if(KeyValue2 == 0)
{
Key_Down_** = 0x05;
}
else
{
Key_Down_** = 0x00;
}
}
if(Key_Down_** == 0x05)
{
LED_ON;
delay_ms(500);
}
else
{
LED_OFF;
}
}
/*******************************************************************
** 函数名称:MotorA_Forward
** 输入参数:无
** 输出参数:无
** 功能描述:
**********************************************************************/
void Motor_Forward(void)
{
MOTOR1_ON; //左轮
MOTOR2_OFF;
MOTOR3_ON; //右轮
MOTOR4_OFF;
}
/*****************************************************************************
** 函数名称:MotorA_Backward
** 输入参数:无
** 输出参数:无
** 功能描述:
*****************************************************************************/
void Motor_Backward(void)
{
MOTOR1_OFF; //左轮
MOTOR2_ON;
MOTOR3_OFF; //右轮
MOTOR4_ON;
}
/***************************************************************************
** 函数名称:MotorB_Forward
** 输入参数:无
** 输出参数:无
** 功能描述:
****************************************************************************/
void Motor_Left(void)
{
MOTOR1_OFF; //左轮
MOTOR2_OFF;
MOTOR3_ON; //右轮
MOTOR4_OFF;
}
/*************************************************************************
** 函数名称:MotorB_Backward
** 输入参数:无
** 输出参数:无
** 功能描述:
**************************************************************************/
void Motor_Right(void)
{
MOTOR1_ON; //左轮
MOTOR2_OFF;
MOTOR3_OFF; //右轮
MOTOR4_OFF;
}
/*******************************************************************************
** 函数名称:Motor_Stop
** 输入参数:无
** 输出参数:无
** 功能描述:
******************************************************************************/
void Motor_Stop(void)
{
MOTOR1_OFF; //左轮
MOTOR2_OFF;
MOTOR3_OFF; //右轮
MOTOR4_OFF;
}
OLED.C文件
#include "stm32f10x_i2c.h"
#include "oled.h"
#include "sys.h"
#define XLevelL 0x00
#define XLevelH 0x10
#define XLevel ((XLevelH&0x0F)*16+XLevelL)
#define Max_Column 128
#define Max_Row 64
#define Brightness 0xCF
#define X_WIDTH 128
#define Y_WIDTH 64
//////////////////////////////////////////////////////////////////////////////////////////////////////////////////
void OLED_Initial()
{
delay_ms(100); //延时
Write_IIC_Command(0xAE); //display off
Write_IIC_Command(0x20); //Set Memory Addressing Mode
Write_IIC_Command(0x10); //00,Horizontal Addressing Mode;01,Vertical Addressing Mode;10
Write_IIC_Command(0xb0); //Set Page Start Address for Page Addressing Mode,0-7
Write_IIC_Command(0xc8); //Set COM Output Scan Direction
Write_IIC_Command(0x00);//---set low column address
Write_IIC_Command(0x10);//---set high column address
Write_IIC_Command(0x40);//--set start line address
Write_IIC_Command(0x81);//--set contrast control register
Write_IIC_Command(0x7f);
Write_IIC_Command(0xa1);//--set segment re-map 0 to 127
Write_IIC_Command(0xa6);//--set normal display
Write_IIC_Command(0xa8);//--set multiplex ratio(1 to 64)
Write_IIC_Command(0x3F);//
Write_IIC_Command(0xa4);//0xa4,Output follows RAM content;0xa5,Output ignores RAM content
Write_IIC_Command(0xd3);//-set display offset
Write_IIC_Command(0x00);//-not offset
Write_IIC_Command(0xd5);//--set display clock divide ratio/oscillator frequency
Write_IIC_Command(0xf0);//--set divide ratio
Write_IIC_Command(0xd9);//--set pre-charge period
Write_IIC_Command(0x22); //
Write_IIC_Command(0xda);//--set com pins hardware configuration
Write_IIC_Command(0x12);
Write_IIC_Command(0xdb);//--set vcomh
Write_IIC_Command(0x20);//0x20,0.77xVcc
Write_IIC_Command(0x8d);//--set DC-DC enable
Write_IIC_Command(0x14);//
Write_IIC_Command(0xaf);//--turn on oled panel
LCD_CLS();
LCD_Set_Pos(0,0);
}
/**********************************************
//IIC Start
**********************************************/
void IIC_Start()
{
SCL_HIGH;
SDA_HIGH;
SDA_LOW;
SCL_LOW;
}
/**********************************************
//IIC Stop
**********************************************/
void IIC_Stop()
{
SCL_LOW;
SDA_LOW;
SCL_HIGH;
SDA_HIGH;
}
/**********************************************
// IIC Write byte
**********************************************/
void Write_IIC_Byte(unsigned char IIC_Byte)
{
unsigned char i;
for(i=0;i<8;i++)
{
if(IIC_Byte&0x80) //1?0?
SDA_HIGH;
else
SDA_LOW;
SCL_HIGH;
SCL_LOW;
IIC_Byte<<=1; //loop
}
SDA_HIGH;
SCL_HIGH;
SCL_LOW;
}
/**********************************************
// IIC Write Command
**********************************************/
void Write_IIC_Command(unsigned char IIC_Command)
{
IIC_Start();
Write_IIC_Byte(0x78); //Slave address,SA0=0
Write_IIC_Byte(0x00); //write command
Write_IIC_Byte(IIC_Command);
IIC_Stop();
}
/**********************************************
// IIC Write Data
**********************************************/
void Write_IIC_Data(unsigned char IIC_Data)
{
IIC_Start();
Write_IIC_Byte(0x78);
Write_IIC_Byte(0x40); //write data
Write_IIC_Byte(IIC_Data);
IIC_Stop();
}
/*********************LCD 设置坐标************************************/
void LCD_Set_Pos(unsigned char x, unsigned char y)
{
Write_IIC_Command(0xb0+y);
Write_IIC_Command(((x&0xf0)>>4)|0x10);
Write_IIC_Command((x&0x0f)|0x01);
}
/*********************OLCD清屏************************************/
void LCD_CLS(void)
{
unsigned char y,x;
for(y=0;y<8;y++)
{
Write_IIC_Command(0xb0+y);
Write_IIC_Command(0x01);
Write_IIC_Command(0x10);
for(x=0;x<X_WIDTH;x++)
Write_IIC_Data(0);
}
}
/*******功能描述:显示6*8一组标准ASCII字符串 显示的坐标(x,y),y为页范围0~7********/
void LCD_P6x8Str(unsigned char x,unsigned char y,unsigned char ch[])
{
unsigned char c=0,i=0,j=0;
while (ch[j]!='\0')
{
c =ch[j]-32;
if(x>126){x=0;y++;}
LCD_Set_Pos(x,y);
for(i=0;i<6;i++)
Write_IIC_Data(F6x8[c][i]);
x+=6;
j++;
}
}
/*********功能描述:显示8*16一组标准ASCII字符串 显示的坐标(x,y),y为页范围0~7*******/
void LCD_P8x16Str(unsigned char x,unsigned char y,unsigned char ch[])
{
unsigned char c=0,i=0,j=0;
while (ch[j]!='\0')
{
c =ch[j]-32;
if(x>120){x=0;y++;}
LCD_Set_Pos(x,y);
for(i=0;i<8;i++)
Write_IIC_Data(F8X16[c*16+i]);
LCD_Set_Pos(x,y+1);
for(i=0;i<8;i++)
Write_IIC_Data(F8X16[c*16+i+8]);
x+=8;
j++;
}
}
/*******功能描述:显示16*16点阵 显示的坐标(x,y),y为页范围0~7***********/
void LCD_P16x16Ch(unsigned char x,unsigned char y,unsigned char N)
{
unsigned char wm=0;
unsigned int adder=32*N; //
LCD_Set_Pos(x , y);
for(wm = 0;wm < 16;wm++) //
{
Write_IIC_Data(F16x16[adder]);
adder += 1;
}
LCD_Set_Pos(x,y + 1);
for(wm = 0;wm < 16;wm++) //
{
Write_IIC_Data(F16x16[adder]);
adder += 1;
}
}
/******功能描述:显示显示BMP图片128×64起始点坐标(x,y),x的范围0~127,y为页的范围0~7*********/
void Draw_BMP(unsigned char x0,unsigned char y0,unsigned char x1,unsigned char y1,unsigned char BMP[])
{
unsigned int j=0;
unsigned char x,y;
if(y1%8==0) y=y1/8;
else y=y1/8+1;
for(y=y0;y<y1;y++)
{
LCD_Set_Pos(x0,y);
for(x=x0;x<x1;x++)
{
Write_IIC_Data(BMP[j++]);
}
}
}
/******功能描述:显示显示BMP图片128×64起始点坐标(x,y),x的范围0~127,y为页的范围0~7***********/
void itoafunc(unsigned int number,unsigned char NumStr[])
{
unsigned char ch[6];
int i,j;
for(i=0;i<6;i++)
{
ch[i] = 0;
NumStr[i] = 0;
}
if(number<=9)
{
ch[0] = number + '0';
ch[1] = 0 + '0';
ch[2] = 0 + '0';
i = 2;
}
else
{
for(i=0;number!=0;number/=10,i++)
{
ch[i]=number%10 + '0';
}
}
if(i < 6)
{
for(j=0;i>=0;i--)
NumStr[j++]=ch[i];
}
}