STM32F102ZET6最小系统制作
1.功能需求
(1)一路DAC输出
(2)两路PWM输出
(3)两路普通GPIO输出
(4)RS485
(5)USB供电+串口
(6)复位电路
(7)蓝牙传输
(8)LCD屏幕显示
(9)输出光耦隔离
(10)电源指示灯LED,两个其他LED
2.原理图绘制
采用AD20,根据正点原子F103ZET6开发板的原理图进行绘制,要求实现上述功能
3.PCB绘制
绘制好原理图,在封装管理器中设置好对应的元器件封装,然后导入到PCB中,进行PCB布线,泪滴,铺铜,绘制好的PCB如下所示。
4.实物展示
5.程序源码
#include "led.h"
#include "delay.h"
#include "key.h"
#include "sys.h"
#include "lcd.h"
#include "usart.h"
#include "hc05.h"
#include "usart3.h"
#include "string.h"
#include "usmart.h"
#include "timer.h"
#include "absolute_encoder.h"
#include "speedcontrol.h"
#include "break.h"
/***********************************************************************
***********************************************************************
* 名 称:HC05_Role_Show
* 说 明:获取蓝牙模块的状态
* 日 期:2020/06/02
***********************************************************************/
void HC05_Role_Show(void)
{
if(HC05_Get_Role()==1)LED1=0;
// if(HC05_Get_Role()==1)LCD_ShowString(30,140,200,16,16,"ROLE:Master");
else LED1=0;
}
/***********************************************************************
***********************************************************************
* 名 称:主程序
* 说 明:完成485初始化,LCD初始化,角度获取,LCD显示程序调用等
蓝牙模块初始化,蓝牙指令的获取,以及动作命令的执行
* 日 期:2020/05/31
***********************************************************************/
int main(void)
{
u32 Angle = 0;
u32 Angle2 = 0;
u8 t;
u8 x=0;
u8 key;
u8 reclen=0;
u16 led0pwmval=0;
u8 sendmask=0;
u8 sendcnt=0;
u8 sendbuf[20];
u8 lcd_id[12]; //存放LCD ID字符串
delay_init(); //延时函数初始化
NVIC_PriorityGroupConfig(NVIC_PriorityGroup_2); //设置NVIC中断分组2:2位抢占优先级,2位响应优先级
uart_init(115200); //串口初始化为115200
LED_Init(); //LED端口初始化
LCD_Init();
POINT_COLOR=RED;
sprintf((char*)lcd_id,"LCD ID:%04X",lcddev.id);//将LCD ID打印到lcd_id数组。
AbsoluteEncoders_Init();
TIM3_PWM_Init(8999,0);
Dac2_Init(); //速度控制信号输出
Turn_Init();//
LCD_ShowString(30,50,200,16,16,"The Angle of wheel");
usmart_dev.init(72);
/***********************************************************************
***********************************************************************
* 名 称:HC05_Init()
* 说 明:初始化HC05模块,并在LCD出其状态
* 日 期:2020/06/02
***********************************************************************/
while(HC05_Init()) //???ATK-HC05??
{
LCD_ShowString(30,90,200,16,16,"ATK-HC05 Error!");
delay_ms(500);
LCD_ShowString(30,90,200,16,16,"Please Check!!!");
delay_ms(100);
}
LCD_ShowString(30,90,210,16,16,"KEY1:ROLE KEY0:SEND/STOP");
// LCD_ShowString(30,110,200,16,16,"ATK-HC05 Standby!");
LCD_ShowString(30,160,200,16,16,"Send:");
LCD_ShowString(30,180,200,16,16,"Receive:");
POINT_COLOR=BLUE;
HC05_Role_Show();
delay_ms(100);
USART3_RX_STA=0;
while(1)
{
key=KEY_Scan(0);
if(key==KEY1_PRES)
{
key=HC05_Get_Role();
if(key!=0XFF)
{
key=!key;
if(key==0)HC05_Set_Cmd("AT+ROLE=0");
else HC05_Set_Cmd("AT+ROLE=1");
HC05_Role_Show();
HC05_Set_Cmd("AT+RESET");
delay_ms(200);
}
}else if(key==KEY0_PRES)
{
sendmask=!sendmask;
if(sendmask==0)LCD_Fill(30+40,160,240,160+16,WHITE);
}else delay_ms(10);
if(t==50)
{
if(sendmask)
{
sprintf((char*)sendbuf,"ALIENTEK HC05 %drn",sendcnt);
LCD_ShowString(30+40,160,200,16,16,sendbuf);
u3_printf("ALIENTEK HC05 %drn",sendcnt);
sendcnt++;
if(sendcnt>99)sendcnt=0;
}
// HC05_Sta_Show();
t=0;
// LED0=!LED0;
}
if(USART3_RX_STA&0X8000)
{
LCD_Fill(30,200,240,320,WHITE);
reclen=USART3_RX_STA&0X7FFF;
USART3_RX_BUF[reclen]=0;
if(reclen==4)
{
/****************转向模块**********************/
if(strcmp((const char*)USART3_RX_BUF,"righ")==0)
{
turn_left = 1; // 此处使用PF0控制正反转控制左右
turn_right = 1;
delay_us(20); // 延时12微秒表示转向信号必须在pwm信号之前输出;
led0pwmval=3000;
TIM_SetCompare2(TIM3,led0pwmval); //PB5发送脉冲
// delay_ms(500);
TIM_SetCompare1(TIM3,led0pwmval);
}
if(strcmp((const char*)USART3_RX_BUF,"stop")==0)
{
led0pwmval=0;
TIM_SetCompare2(TIM3,led0pwmval);
TIM_SetCompare1(TIM3,led0pwmval);
// delay_ms(500);
}
if(strcmp((const char*)USART3_RX_BUF,"left")==0)
{
turn_right = 0;
turn_left=0; // 此处使用PF05控制正反转
delay_us(20); // 延时12微秒表示转向信号必须在pwm信号之前输出;
led0pwmval=3000;
TIM_SetCompare2(TIM3,led0pwmval);
TIM_SetCompare1(TIM3,led0pwmval);
// delay_ms(500);
}
/**************转向特殊功能模块,90度,45转向,置零*******************/
if(strcmp((const char*)USART3_RX_BUF,"nine")==0)
{
Angle= Wheel_GetAngle(01);
while((Angle<90|Angle>=270)&&(Angle!=361))
{
// Angle= Wheel_GetAngle(01);
turn_left=0; // 此处使用PE5控制正反转,顺时针
delay_us(10); // 延时12微秒表示转向信号必须在pwm信号之前输出;
led0pwmval=3000;
TIM_SetCompare2(TIM3,led0pwmval);
// delay_ms(500);
Angle= Wheel_GetAngle(01);
u8 flag=1;
while(Angle>=89&&flag==1)
{
led0pwmval=0;
TIM_SetCompare2(TIM3,led0pwmval);
flag=0;
// delay_ms(500);
}
}
while(Angle>90&&Angle<270)
{
// Angle= Wheel_GetAngle(01);
turn_left=1; // 此处使用PE5控制正反转
delay_us(10); // 延时12微秒表示转向信号必须在pwm信号之前输出;
led0pwmval=3000;
TIM_SetCompare2(TIM3,led0pwmval);
// delay_ms(500);
Angle= Wheel_GetAngle(01);
u8 flag=1;
while(Angle<=91&&flag==1)
{
// led0pwmval=0;
TIM_SetCompare2(TIM3,0);
flag=0;
// delay_ms(500);
}
}
}
/*************此程序用于将编码器置零*****************/
if(strcmp((const char*)USART3_RX_BUF,"zero")==0)
{
Angel_To_Zero(0x01);
Angle = Wheel_GetAngle(0x01);
LCD_ShowNum(30,270,Angle,4,16);
}
/****************两转向单独控制模块**************/
if(strcmp((const char*)USART3_RX_BUF,"ltol")==0)
{
turn_left = 0; // 此处使用PF0控制正反转控制左右
delay_us(20); // 延时12微秒表示转向信号必须在pwm信号之前输出;
led0pwmval=1000;
TIM_SetCompare2(TIM3,led0pwmval); //PB5发送脉冲
}
if(strcmp((const char*)USART3_RX_BUF,"ltor")==0)
{
turn_left = 1; // 此处使用PF0控制正反转控制左右
delay_us(20); // 延时12微秒表示转向信号必须在pwm信号之前输出;
led0pwmval=1000;
TIM_SetCompare2(TIM3,led0pwmval); //PB5发送脉冲
}
if(strcmp((const char*)USART3_RX_BUF,"rtol")==0)
{
turn_right = 0; // 此处使用PF0控制正反转控制左右
delay_us(20); // 延时12微秒表示转向信号必须在pwm信号之前输出;
led0pwmval=2000;
TIM_SetCompare1(TIM3,led0pwmval); //PB4发送脉冲
}
if(strcmp((const char*)USART3_RX_BUF,"rtor")==0)
{
turn_right = 1; // 此处使用PF0控制正反转控制左右
delay_us(20); // 延时12微秒表示转向信号必须在pwm信号之前输出;
led0pwmval=2000;
TIM_SetCompare1(TIM3,led0pwmval); //PB4发送脉冲
}
/***********轮毂电机模块*************************/
if(strcmp((const char*)USART3_RX_BUF,"acce")==0)
{
u16 speed = 1000;
while(strcmp((const char*)USART3_RX_BUF,"acce")==0&&speed<1500)
{
Dac2_Set_Vol(speed);
speed = speed+1;
delay_ms(1);
}
}
if(strcmp((const char*)USART3_RX_BUF,"sttp")==0)
{
u16 speed = 0;
Dac2_Set_Vol(speed);
// delay_ms(5000);
// break_left = 1;
}
}
LCD_ShowString(30,200,209,119,16,USART3_RX_BUF);
USART3_RX_STA=0;
}
t++;
Angle = Wheel_GetAngle(0x01);
LCD_ShowNum(30,220,Angle,4,16);
}
}
6.总结
通过制作,熟悉了AD软件操作,封装的一些基础知识,初步了解到无源器件的使用指南。
STM32F102ZET6最小系统制作
1.功能需求
(1)一路DAC输出
(2)两路PWM输出
(3)两路普通GPIO输出
(4)RS485
(5)USB供电+串口
(6)复位电路
(7)蓝牙传输
(8)LCD屏幕显示
(9)输出光耦隔离
(10)电源指示灯LED,两个其他LED
2.原理图绘制
采用AD20,根据正点原子F103ZET6开发板的原理图进行绘制,要求实现上述功能
3.PCB绘制
绘制好原理图,在封装管理器中设置好对应的元器件封装,然后导入到PCB中,进行PCB布线,泪滴,铺铜,绘制好的PCB如下所示。
4.实物展示
5.程序源码
#include "led.h"
#include "delay.h"
#include "key.h"
#include "sys.h"
#include "lcd.h"
#include "usart.h"
#include "hc05.h"
#include "usart3.h"
#include "string.h"
#include "usmart.h"
#include "timer.h"
#include "absolute_encoder.h"
#include "speedcontrol.h"
#include "break.h"
/***********************************************************************
***********************************************************************
* 名 称:HC05_Role_Show
* 说 明:获取蓝牙模块的状态
* 日 期:2020/06/02
***********************************************************************/
void HC05_Role_Show(void)
{
if(HC05_Get_Role()==1)LED1=0;
// if(HC05_Get_Role()==1)LCD_ShowString(30,140,200,16,16,"ROLE:Master");
else LED1=0;
}
/***********************************************************************
***********************************************************************
* 名 称:主程序
* 说 明:完成485初始化,LCD初始化,角度获取,LCD显示程序调用等
蓝牙模块初始化,蓝牙指令的获取,以及动作命令的执行
* 日 期:2020/05/31
***********************************************************************/
int main(void)
{
u32 Angle = 0;
u32 Angle2 = 0;
u8 t;
u8 x=0;
u8 key;
u8 reclen=0;
u16 led0pwmval=0;
u8 sendmask=0;
u8 sendcnt=0;
u8 sendbuf[20];
u8 lcd_id[12]; //存放LCD ID字符串
delay_init(); //延时函数初始化
NVIC_PriorityGroupConfig(NVIC_PriorityGroup_2); //设置NVIC中断分组2:2位抢占优先级,2位响应优先级
uart_init(115200); //串口初始化为115200
LED_Init(); //LED端口初始化
LCD_Init();
POINT_COLOR=RED;
sprintf((char*)lcd_id,"LCD ID:%04X",lcddev.id);//将LCD ID打印到lcd_id数组。
AbsoluteEncoders_Init();
TIM3_PWM_Init(8999,0);
Dac2_Init(); //速度控制信号输出
Turn_Init();//
LCD_ShowString(30,50,200,16,16,"The Angle of wheel");
usmart_dev.init(72);
/***********************************************************************
***********************************************************************
* 名 称:HC05_Init()
* 说 明:初始化HC05模块,并在LCD出其状态
* 日 期:2020/06/02
***********************************************************************/
while(HC05_Init()) //???ATK-HC05??
{
LCD_ShowString(30,90,200,16,16,"ATK-HC05 Error!");
delay_ms(500);
LCD_ShowString(30,90,200,16,16,"Please Check!!!");
delay_ms(100);
}
LCD_ShowString(30,90,210,16,16,"KEY1:ROLE KEY0:SEND/STOP");
// LCD_ShowString(30,110,200,16,16,"ATK-HC05 Standby!");
LCD_ShowString(30,160,200,16,16,"Send:");
LCD_ShowString(30,180,200,16,16,"Receive:");
POINT_COLOR=BLUE;
HC05_Role_Show();
delay_ms(100);
USART3_RX_STA=0;
while(1)
{
key=KEY_Scan(0);
if(key==KEY1_PRES)
{
key=HC05_Get_Role();
if(key!=0XFF)
{
key=!key;
if(key==0)HC05_Set_Cmd("AT+ROLE=0");
else HC05_Set_Cmd("AT+ROLE=1");
HC05_Role_Show();
HC05_Set_Cmd("AT+RESET");
delay_ms(200);
}
}else if(key==KEY0_PRES)
{
sendmask=!sendmask;
if(sendmask==0)LCD_Fill(30+40,160,240,160+16,WHITE);
}else delay_ms(10);
if(t==50)
{
if(sendmask)
{
sprintf((char*)sendbuf,"ALIENTEK HC05 %drn",sendcnt);
LCD_ShowString(30+40,160,200,16,16,sendbuf);
u3_printf("ALIENTEK HC05 %drn",sendcnt);
sendcnt++;
if(sendcnt>99)sendcnt=0;
}
// HC05_Sta_Show();
t=0;
// LED0=!LED0;
}
if(USART3_RX_STA&0X8000)
{
LCD_Fill(30,200,240,320,WHITE);
reclen=USART3_RX_STA&0X7FFF;
USART3_RX_BUF[reclen]=0;
if(reclen==4)
{
/****************转向模块**********************/
if(strcmp((const char*)USART3_RX_BUF,"righ")==0)
{
turn_left = 1; // 此处使用PF0控制正反转控制左右
turn_right = 1;
delay_us(20); // 延时12微秒表示转向信号必须在pwm信号之前输出;
led0pwmval=3000;
TIM_SetCompare2(TIM3,led0pwmval); //PB5发送脉冲
// delay_ms(500);
TIM_SetCompare1(TIM3,led0pwmval);
}
if(strcmp((const char*)USART3_RX_BUF,"stop")==0)
{
led0pwmval=0;
TIM_SetCompare2(TIM3,led0pwmval);
TIM_SetCompare1(TIM3,led0pwmval);
// delay_ms(500);
}
if(strcmp((const char*)USART3_RX_BUF,"left")==0)
{
turn_right = 0;
turn_left=0; // 此处使用PF05控制正反转
delay_us(20); // 延时12微秒表示转向信号必须在pwm信号之前输出;
led0pwmval=3000;
TIM_SetCompare2(TIM3,led0pwmval);
TIM_SetCompare1(TIM3,led0pwmval);
// delay_ms(500);
}
/**************转向特殊功能模块,90度,45转向,置零*******************/
if(strcmp((const char*)USART3_RX_BUF,"nine")==0)
{
Angle= Wheel_GetAngle(01);
while((Angle<90|Angle>=270)&&(Angle!=361))
{
// Angle= Wheel_GetAngle(01);
turn_left=0; // 此处使用PE5控制正反转,顺时针
delay_us(10); // 延时12微秒表示转向信号必须在pwm信号之前输出;
led0pwmval=3000;
TIM_SetCompare2(TIM3,led0pwmval);
// delay_ms(500);
Angle= Wheel_GetAngle(01);
u8 flag=1;
while(Angle>=89&&flag==1)
{
led0pwmval=0;
TIM_SetCompare2(TIM3,led0pwmval);
flag=0;
// delay_ms(500);
}
}
while(Angle>90&&Angle<270)
{
// Angle= Wheel_GetAngle(01);
turn_left=1; // 此处使用PE5控制正反转
delay_us(10); // 延时12微秒表示转向信号必须在pwm信号之前输出;
led0pwmval=3000;
TIM_SetCompare2(TIM3,led0pwmval);
// delay_ms(500);
Angle= Wheel_GetAngle(01);
u8 flag=1;
while(Angle<=91&&flag==1)
{
// led0pwmval=0;
TIM_SetCompare2(TIM3,0);
flag=0;
// delay_ms(500);
}
}
}
/*************此程序用于将编码器置零*****************/
if(strcmp((const char*)USART3_RX_BUF,"zero")==0)
{
Angel_To_Zero(0x01);
Angle = Wheel_GetAngle(0x01);
LCD_ShowNum(30,270,Angle,4,16);
}
/****************两转向单独控制模块**************/
if(strcmp((const char*)USART3_RX_BUF,"ltol")==0)
{
turn_left = 0; // 此处使用PF0控制正反转控制左右
delay_us(20); // 延时12微秒表示转向信号必须在pwm信号之前输出;
led0pwmval=1000;
TIM_SetCompare2(TIM3,led0pwmval); //PB5发送脉冲
}
if(strcmp((const char*)USART3_RX_BUF,"ltor")==0)
{
turn_left = 1; // 此处使用PF0控制正反转控制左右
delay_us(20); // 延时12微秒表示转向信号必须在pwm信号之前输出;
led0pwmval=1000;
TIM_SetCompare2(TIM3,led0pwmval); //PB5发送脉冲
}
if(strcmp((const char*)USART3_RX_BUF,"rtol")==0)
{
turn_right = 0; // 此处使用PF0控制正反转控制左右
delay_us(20); // 延时12微秒表示转向信号必须在pwm信号之前输出;
led0pwmval=2000;
TIM_SetCompare1(TIM3,led0pwmval); //PB4发送脉冲
}
if(strcmp((const char*)USART3_RX_BUF,"rtor")==0)
{
turn_right = 1; // 此处使用PF0控制正反转控制左右
delay_us(20); // 延时12微秒表示转向信号必须在pwm信号之前输出;
led0pwmval=2000;
TIM_SetCompare1(TIM3,led0pwmval); //PB4发送脉冲
}
/***********轮毂电机模块*************************/
if(strcmp((const char*)USART3_RX_BUF,"acce")==0)
{
u16 speed = 1000;
while(strcmp((const char*)USART3_RX_BUF,"acce")==0&&speed<1500)
{
Dac2_Set_Vol(speed);
speed = speed+1;
delay_ms(1);
}
}
if(strcmp((const char*)USART3_RX_BUF,"sttp")==0)
{
u16 speed = 0;
Dac2_Set_Vol(speed);
// delay_ms(5000);
// break_left = 1;
}
}
LCD_ShowString(30,200,209,119,16,USART3_RX_BUF);
USART3_RX_STA=0;
}
t++;
Angle = Wheel_GetAngle(0x01);
LCD_ShowNum(30,220,Angle,4,16);
}
}
6.总结
通过制作,熟悉了AD软件操作,封装的一些基础知识,初步了解到无源器件的使用指南。
举报