本帖最后由 flytohign 于 2020-6-9 10:23 編輯
本項目采用STM32單片機和L298電機驅動模塊,簡單連線制作;后期會加入避障和循跡功能;/************************************************
開發板:STM32F10x+L298N直流電機驅動器
項目名稱:基于STM32紅外遙控智能小車設計
功能:1.紅外遙控小車前進、后退,左轉彎、右轉彎
2.小車前進后退0-10檔加減速、指定檔位變速
端口定義:IN1--GPIOC_pin0
IN2--GPIOC_pin1
IN3--GPIOC_pin2
IN4--GPIOC_pin3
ENA--GPIOF_pin0
ENB--GPIOF_pin1
STM32電源---VCC 3.3V
電源配置:直流電機驅動L298電源--VCC 6.0V
特別注意:電機驅動和單片機分別供電,要特別主要STM32單片機和L298N共地連接
這個我開始沒注意,花費了不少時間
日期:2020年6月4日,第一次
************************************************/
1.硬件選型
L298使用說明_愛奇藝.jpg (125.54 KB, 下載次數: 38)
下載附件
2020-6-8 22:50 上傳
由于程序設計過程中涉及第三方代碼,我貼出我自己設計的主要函數,應該很容易能夠搭建項目的;
主要設計函數就是我定義的motorcon.h和motorcon.c文件,包括一些紅外小車的前進、后退、左轉和右轉,暫停等;
在中斷函數exti.c和exti.h中完成紅外遙控信號的識別,并數據處理;
捕獲.PNG (11.24 KB, 下載次數: 38)
下載附件
2020-6-9 10:19 上傳
2.源程序
主函數
- #include "led.h"
- #include "delay.h"
- #include "key.h"
- #include "sys.h"
- #include "lcd.h"
- #include "usart.h"
- #include "remote.h"
- #include "motorcon.h"
- #include "exti.h"
- #include "beep.h"
- /************************************************
- 開發板:STM32F10x+L298N直流電機驅動器
- 項目名稱:基于STM32紅外遙控智能小車設計
- <font color="#ff0000">功能:1.紅外遙控小車前進、后退,左轉彎、右轉彎
- 2.小車前進后退0-10檔加減速、指定檔位變速</font>
- 端口定義:IN1--GPIOC_pin0
- IN2--GPIOC_pin1
- IN3--GPIOC_pin2
- IN4--GPIOC_pin3
- ENA--GPIOF_pin0
- ENB--GPIOF_pin1
- STM32電源---VCC 3.3V
- 電源配置:直流電機驅動L298電源--VCC 6.0V
- 特別注意:STM32單片機和L298N共地連接
- 日期:2020年6月4日,第一次
- ************************************************/
- int main(void)
- {
-
- delay_init(); //延時函數初始化
- NVIC_PriorityGroupConfig(NVIC_PriorityGroup_2);//設置中斷優先級分組為組2:2位搶占優先級,2位響應優先級
- uart_init(115200); //串口初始化為115200
- LED_Init(); //LED端口初始化
- LCD_Init();
- KEY_Init();
- Remote_Init(); //紅外接收初始化
- Motor_IOconfig(); //電機端口初始化
- BEEP_Init(); //初始化蜂鳴器IO
- EXTIX_Init(); //初始化外部中斷輸入
-
- POINT_COLOR=RED; //設置字體為紅色
- LCD_ShowString(30,50,200,16,16,"STM32+L289N");
- LCD_ShowString(30,70,200,16,16,"REMOTE INTELLIGENCE CAR");
- LCD_ShowString(30,90,200,16,16,"PARAMETER DISPLAY");
- LCD_ShowString(30,110,200,16,16,"2020/6/4");
- LCD_ShowString(30,130,200,16,16,"KEYVALA:");
- LCD_ShowString(30,150,200,16,16,"KEYCONT:");
- LCD_ShowString(30,170,200,16,16,"SYMBOLY:");
- LCD_ShowString(30,190,200,16,16,"SPEED LEVEL:");
- while(1)
- {
-
- if(flagforward==1)
- {motor_Sforward();}
- if(flagback==1)
- {motor_Sback();}
- // if(flagleft==1)
- // {motor_left();}
- // if(flagright==1)
- // {motor_right();}
- // if(flagstop==1)
- // {motor_stop();}
- }
- }
復制代碼
頭文件exti.h
定義了外部變量flagforward,flagback和num,di_num,gao_num
- #ifndef __EXTI_H
- #define __EXIT_H
- #include "sys.h"
-
- void EXTIX_Init(void);//外部中斷初始化
- extern u8 flagforward,flagback;//flagleft,flagright,flagstop;
- extern u8 num,di_num,gao_num;
- #endif
復制代碼
源程序exti.c
中斷程序,采用重映射功能將紅外接收端口映射到中斷線;這一步很重要;
然后根據中斷函數的紅外接收號,執行相應功能;
這里特別注意前進和后退的中斷識別設計,采用flagforward,flagback標志位來標記前進和后退指令;
這一步想了好久,不這樣的話前進和后退 小車沒反應;
- #include "exti.h"
- #include "led.h"
- #include "key.h"
- #include "delay.h"
- #include "usart.h"
- #include "beep.h"
- #include "remote.h"
- #include "lcd.h"
- #include "motorcon.h"
- //外部中斷0服務程序,0-15位IO中斷
- void EXTIX_Init(void)
- {
- EXTI_InitTypeDef EXTI_InitStructure;
- NVIC_InitTypeDef NVIC_InitStructure;
- RCC_APB2PeriphClockCmd(RCC_APB2Periph_AFIO,ENABLE); //使能復用功能時鐘
- //GPIOB.9 中斷線以及中斷初始化配置 下降沿觸發 //REMOTE IN
- GPIO_EXTILineConfig(GPIO_PortSourceGPIOB,GPIO_PinSource9);//GPIO與中斷線的映射關系
- EXTI_InitStructure.EXTI_Line=EXTI_Line9; //中斷線9,取值范圍為0-15
- EXTI_InitStructure.EXTI_Mode = EXTI_Mode_Interrupt; //中斷模式
- EXTI_InitStructure.EXTI_Trigger = EXTI_Trigger_Falling;//下降沿觸發中斷
- EXTI_Init(&EXTI_InitStructure);
- //NVIC中斷優先級設置
- NVIC_InitStructure.NVIC_IRQChannel = EXTI9_5_IRQn; //使能紅外接收二極管所對應的外部中斷通道
- NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = 0x00; //搶占優先級2,
- NVIC_InitStructure.NVIC_IRQChannelSubPriority = 0x01; //子優先級0
- NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE; //使能外部中斷通道
- NVIC_Init(&NVIC_InitStructure);
-
- }
- u8 key;
- u8 flagforward=0,flagback=0;//flagleft=0,flagright=0,flagstop=0;
- u8 num=0,di_num=10,gao_num=0;
- //外部中斷9服務程序 ,中斷線5-9
- void EXTI9_5_IRQHandler(void)
- {
-
- if(EXTI_GetITStatus(EXTI_Line9)!=RESET) //判斷某個中斷線是否有中斷產生
- {
- u8 *str=0; //***定義字符換指針str**//
- key=Remote_Scan(); //接收紅外發送數值
- if(key)
- {
- LCD_ShowNum(86,130,key,3,16); //顯示鍵值
- LCD_ShowNum(86,150,RmtCnt,3,16); //顯示按鍵次數
- switch(key)
- {
- case 0:str="ERROR";break;
- case 162:str="POWER"; //停車
- // flagstop=1;
- motor_stop();
- break;
- case 98:str="UP";
- flagforward=1,flagback=0; //前進
- break;
- case 2:str="PLAY";break;
- case 226:str="ALIENTEK";break;
- case 194:str="RIGHT"; //右轉
- // flagright=1,flagleft=0;
- motor_right();
- break;
- case 34:str="LEFT"; //左轉
- // flagleft=1,flagright=0;
- motor_left();
- break;
- case 224:str="VOL-"; //減速
- if(num!=0)
- num--;
- else
- num=0;
- motor_reddisp();
- break;
- case 168:str="DOWN"; //后退
- flagback=1,flagforward=0;
- break;
- case 144:str="VOL+"; //加速
- num++;
- if(num==10)
- num=10;
- motor_reddisp();
- break;
-
- case 104:str="1";num=0;gao_num=0;di_num=10;break; //指定檔位
- case 152:str="2";num=1;gao_num=1;di_num=9;break;
- case 176:str="3";num=2;gao_num=2;di_num=8;break;
- case 48:str="4";num=3;gao_num=3;di_num=7;break;
- case 24:str="5";num=4;gao_num=4;di_num=6;break;
- case 122:str="6";num=5;gao_num=5;di_num=5;break;
- case 16:str="7";num=6;gao_num=6;di_num=4;break;
- case 56:str="8";num=7;gao_num=7;di_num=3;break;
- case 90:str="9";num=8;gao_num=8;di_num=2;break;
- case 66:str="0";num=9;gao_num=9;di_num=1;break;
- case 82:str="DELETE";num=10;gao_num=10;di_num=0;break;
- }
- LCD_Fill(86,170,116+8*8,170+16,WHITE); //清楚之前的顯示
- LCD_ShowString(86,170,200,16,16,str); //顯示SYMBOLY
- LCD_ShowNum(86,190,num,3,16); //顯示按鍵次數
-
- }
- BEEP=!BEEP;
- EXTI_ClearITPendingBit(EXTI_Line9); //清除LINE0上的中斷標志位
- }
-
- }
復制代碼
源文件motorcon.h
定義了一些端口;
還有電機控制函數;
- #ifndef _MOTORCON_H
- #define _MOTORCON_H
- #include "sys.h"
- #define uint unsigned int
- #define uchar unsigned char
- #define IN1 PCout(0)
- #define IN2 PCout(1)
- #define IN3 PCout(2)
- #define IN4 PCout(3)
- #define ENA PFout(0)
- #define ENB PFout(1)
- void Motor_IOconfig(void);
- void motor_Sforward(void);
- void motor_Sback(void);
- void motor_left(void);
- void motor_right(void);
- void motor_stop(void);
- void motor_redkchange(void);
- void motor_reddisp(void);
- #endif
復制代碼
源程序motorcon.c
這一步為核心控制環節;
分別設計了前進和后退的PWM控制函數。實現小車 的前進后退的變速運行;
檔位可能具體數值有問題,但是能基本實現變速調節;效果不錯;
- #include "motorcon.h"
- extern u8 num,di_num,gao_num;
- void Motor_IOconfig()
- {
- GPIO_InitTypeDef GPIO_InitStructure;
- RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOC|RCC_APB2Periph_GPIOF,ENABLE); //使能GPIOC和GPIOF端口時鐘
-
- GPIO_InitStructure.GPIO_Pin =GPIO_Pin_0|GPIO_Pin_1|GPIO_Pin_2|GPIO_Pin_3; //GPIOC端口配置
- GPIO_InitStructure.GPIO_Mode =GPIO_Mode_Out_PP; //推挽輸出
- GPIO_InitStructure.GPIO_Speed =GPIO_Speed_50MHz; //IO口速度為50MHz
- GPIO_Init(GPIOC, &GPIO_InitStructure);
- GPIO_ResetBits(GPIOC,GPIO_Pin_0|GPIO_Pin_1|GPIO_Pin_2|GPIO_Pin_3);
- //GPIO_C的0,1,2,3端口初始化為低電平,即IN1-IN4端口
-
- GPIO_InitStructure.GPIO_Pin =GPIO_Pin_0|GPIO_Pin_1;//設置引腳模式為推免輸出模式,,IO口速度為50MHz
- GPIO_Init(GPIOF,&GPIO_InitStructure);
- GPIO_ResetBits(GPIOF,GPIO_Pin_0|GPIO_Pin_1); //GPIO_F的0,1端口初始化為低電平,即ENA端口
- }
- /*電機前進函數*/
- void motor_Sforward()
- {
- uchar i;
- IN1=1;
- IN2=0;
-
- for(i=0;i<di_num;i++)
- {
- ENA=0; //PWM低電平輸出
- }
- for(i=0;i<gao_num;i++)
- {
- ENA=1; //PWM高電平輸出
- }
-
- }
- /*電機后退函數*/
- void motor_Sback()
- {
- uchar i;
- IN1=0;
- IN2=1;
- for(i=0;i<di_num;i++)
- {
- ENA=0;
- }
- for(i=0;i<gao_num;i++)
- {
- ENA=1;
- }
- }
- /*左轉彎函數*/
- void motor_left()
- {
- ENB=1;
- IN3=0;
- IN4=1;
-
- }
- /*右轉彎函數*/
- void motor_right()
- {
- ENB=1;
- IN3=1;
- IN4=0;
-
- }
- /*電機停止函數*/
- void motor_stop()
- {
- ENA=0;
- ENB=0;
- }
- /*紅外數據處理函數*/
- void motor_reddisp()
- {
- switch(num)
- {
- case 0:
- gao_num=0; //高電平持續時間為1,低電平為3
- di_num=10;
- break;
- case 1:
- gao_num=1; //高電平持續時間為8,低電平持續時間為2
- di_num=9;
- break;
- case 2:
- gao_num=2; //高電平持續時間為7,低電平持續時間為3
- di_num=8;
- break;
- case 3:
- gao_num=3; //高電平持續時間為6,低電平持續時間為4
- di_num=7;
- break;
- case 4:
- gao_num=4; //高電平持續時間為5,低電平持續時間為5
- di_num=6;
- break;
- case 5:
- gao_num=5; //高電平持續時間為4,低電平持續時間為0
- di_num=5;
- break;
- case 6:
- gao_num=6; //高電平持續時間為6,低電平持續時間為4
- di_num=4;
- break;
- case 7:
- gao_num=7; //高電平持續時間為7,低電平持續時間為3
- di_num=3;
- break;
- case 8:
- gao_num=8; //高電平持續時間為8,低電平持續時間為2
- di_num=2;
- break;
- case 9:
- gao_num=9; //高電平持續時間為9,低電平持續時間為1
- di_num=1;
- break;
- case 10:
- gao_num=10; //高電平持續時間為10,低電平持續時間為0
- di_num=0;
- break;
- }
- }
復制代碼
硬件實物設計
實物很簡單,通過一個L298驅動器驅動前后輪,前輪轉向,后輪驅動前進后退;
在加入任一單片機控制器就可以制作了。要實現變檔,估計單純的51/52單片機很難實現。
51hei圖片20200609095902.jpg (3.68 MB, 下載次數: 36)
下載附件
2020-6-9 10:21 上傳
51hei圖片20200609095852.jpg (2.18 MB, 下載次數: 36)
下載附件
2020-6-9 10:21 上傳
|