初中生
最后登录1970-1-1
在线时间 小时
注册时间2023-8-16
|
本帖最后由 lyh_fly 于 2023-8-20 23:47 编辑
1.项目设计简介
本项目一开始想用瑞萨的mcu作为主控,两个编码电机作为动力装置,一个万向轮提高车子的机动性、搭载蓝牙模块、DHT11模块、火焰传感器模块、WiFi模块、利用这些获取当时周围环境的温度、湿度信息,还有是否有火源的信息
发送到手机或者上位机,小车也有0.96寸OLED屏幕显示上传的信息。
小车整体状况
小车整体情况
2.所用到的模块
火焰传感器模块
1、可以检测火焰或者波长在760纳米~1100纳米范围内的光源,
打火机测试火焰距离为80cm,对火焰越大,测试距离越远
2)探测角度6o度左右,对火焰光谱特别灵敏
3、灵敏度可调(图中蓝色数字电位器调节)
4、比较器输出,信号干净,波形好,驱动能力强,超过15mA
5、配可调精密电位器调节灵敏度
6、工作电压3.3V-5V
DO引脚输出数字信号
oled屏幕
0.96oled屏幕,利用iic通信总线,可以很好的传输和显示数据
DHT11模块
该模块使用奥松DHT11数字温湿度传感器,DHT11是一款含有已校准数字信号输出的温湿度复合传感器。它应用专用的数字模块采集技术和温湿度传感技术,
确保产品具有可靠的稳定性,响应快,抗干扰能力强。传感器包括一个高分子电阻式感湿元件和一个NTC测温元件,并与一个高性能8位单片机相连接,通
过单总线与微处理器通讯,只需要一根线。
蓝牙模块,利用串口就能发送想要的数据。
手机端控制界面,按下相应的指令能够控制小车的运动和获取当前环境的温湿度
电机驱动模块,采用的整体化设计,便于接线。
3程序设计
oled屏幕采用硬件iic
//==================================================================================================
// 实现功能: 0.96寸OLED 接口演示例程
// 说明:
// GND 电源地
// VCC 接5V或3.3v电源
// SCL 接P505(SCL6)
// SDA 接P506(SDA6)
//==================================================================================================------------------------------------------------------------------------
// | - | - | 0 | 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9
//==================================================================================================
//==================================================================================================
#include "oled.h"
#include "stdlib.h"
#include "oledfont.h"
#include "math.h"
#include "hal_data.h"
extern fsp_err_t err;
extern int timeout_ms;
extern i2c_master_event_t i2c_event ;
//OLED的显存
//存放格式如下.
//[0]0 1 2 3 ... 127
//[1]0 1 2 3 ... 127
//[2]0 1 2 3 ... 127
//[3]0 1 2 3 ... 127
//[4]0 1 2 3 ... 127
//[5]0 1 2 3 ... 127
//[6]0 1 2 3 ... 127
//[7]0 1 2 3 ... 127
//==================================================================================================
// 函数功能: IIC外设驱动函数部分
// 函数标记: Write_IIC_Command
// 函数说明: 无
//-------------------------------------------------------------------------------------------------
// | - | - | 0 | 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9
//==================================================================================================
void Write_IIC_Command(unsigned char IIC_Command)
{
uint8_t ii[2]={0x00,0x00};
ii[1] = IIC_Command;
err = R_SCI_I2C_Write(&g_sci6_i2c_ctrl, ii, 0x02, true);
assert(FSP_SUCCESS == err);
/* Since there is nothing else to do, block until Callback triggers*/
//while ((I2C_MASTER_EVENT_TX_COMPLETE != i2c_event) && timeout_ms)
while ((I2C_MASTER_EVENT_TX_COMPLETE != i2c_event) && timeout_ms>0)
{
R_BSP_SoftwareDelay(100U, BSP_DELAY_UNITS_MICROSECONDS);
timeout_ms--;
}
if (I2C_MASTER_EVENT_ABORTED == i2c_event)
{
__BKPT(0);
}
/* Read data back from the I2C slave */
i2c_event = I2C_MASTER_EVENT_ABORTED;
timeout_ms = 100000;
}
//==================================================================================================
// 函数功能: IIC外设驱动函数部分
// 函数标记: Write_IIC_Data
// 函数说明: 无
//-------------------------------------------------------------------------------------------------
// | - | - | 0 | 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9
//==================================================================================================
void Write_IIC_Data(unsigned char IIC_Data)
{
uint8_t ii[2]={0x40,0x00};
ii[0] = 0x40;
ii[1] = IIC_Data;
err = R_SCI_I2C_Write(&g_sci6_i2c_ctrl, ii, 0x02, true);
assert(FSP_SUCCESS == err);
/* Since there is nothing else to do, block until Callback triggers*/
//while ((I2C_MASTER_EVENT_TX_COMPLETE != i2c_event) && timeout_ms)
while ((I2C_MASTER_EVENT_TX_COMPLETE != i2c_event) && timeout_ms>0)
{
R_BSP_SoftwareDelay(100U, BSP_DELAY_UNITS_MICROSECONDS);
timeout_ms--;
}
if (I2C_MASTER_EVENT_ABORTED == i2c_event)
{
__BKPT(0);
}
/* Read data back from the I2C slave */
i2c_event = I2C_MASTER_EVENT_ABORTED;
timeout_ms = 100000;
}
//==================================================================================================
// 函数功能: IIC外设驱动函数部分
// 函数标记: Write_IIC_Data
// 函数说明: 无
//-------------------------------------------------------------------------------------------------
// | - | - | 0 | 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9
//==================================================================================================
void OLED_WR_Byte(unsigned dat,unsigned cmd)
{
if(cmd)
{
Write_IIC_Data(dat);
}
else
{
Write_IIC_Command(dat);
}
}
/********************************************
// fill_Picture
********************************************/
void fill_picture(unsigned char fill_Data)
{
unsigned char m,n;
for(m=0;m<8;m++)
{
OLED_WR_Byte(0xb0+m,0); //page0-page1
OLED_WR_Byte(0x00,0); //low column start address
OLED_WR_Byte(0x10,0); //high column start address
for(n=0;n<128;n++)
{
OLED_WR_Byte(fill_Data,1);
}
}
}
/***********************Delay****************************************/
void Delay_50ms(unsigned int Del_50ms)
{
unsigned int m;
for(;Del_50ms>0;Del_50ms--)
for(m=6245;m>0;m--);
}
void Delay_1ms(unsigned int Del_1ms)
{
unsigned char j;
while(Del_1ms--)
{
for(j=0;j<123;j++);
}
}
//坐标设置
void OLED_Set_Pos(unsigned char x, unsigned char y)
{ OLED_WR_Byte(0xb0+y,OLED_CMD);
OLED_WR_Byte(((x&0xf0)>>4)|0x10,OLED_CMD);
OLED_WR_Byte((x&0x0f),OLED_CMD);
}
//开启OLED显示
void OLED_Display_On(void)
{
OLED_WR_Byte(0X8D,OLED_CMD); //SET DCDC命令
OLED_WR_Byte(0X14,OLED_CMD); //DCDC ON
OLED_WR_Byte(0XAF,OLED_CMD); //DISPLAY ON
}
//关闭OLED显示
void OLED_Display_Off(void)
{
OLED_WR_Byte(0X8D,OLED_CMD); //SET DCDC命令
OLED_WR_Byte(0X10,OLED_CMD); //DCDC OFF
OLED_WR_Byte(0XAE,OLED_CMD); //DISPLAY OFF
}
//清屏函数,清完屏,整个屏幕是黑色的!和没点亮一样!!!
void OLED_Clear(void)
{
u8 i,n;
for(i=0;i<8;i++)
{
OLED_WR_Byte(0xb0+i,OLED_CMD); //设置页地址(0~7)
OLED_WR_Byte(0x00,OLED_CMD); //设置显示位置—列低地址
OLED_WR_Byte(0x10,OLED_CMD); //设置显示位置—列高地址
for(n=0;n<128;n++)OLED_WR_Byte(0,OLED_DATA);
} //更新显示
}
void OLED_On(void)
{
u8 i,n;
for(i=0;i<8;i++)
{
OLED_WR_Byte (0xb0+i,OLED_CMD); //设置页地址(0~7)
OLED_WR_Byte (0x00,OLED_CMD); //设置显示位置—列低地址
OLED_WR_Byte (0x10,OLED_CMD); //设置显示位置—列高地址
for(n=0;n<128;n++)OLED_WR_Byte(1,OLED_DATA);
} //更新显示
}
//在指定位置显示一个字符,包括部分字符
//x:0~127
//y:0~63
//mode:0,反白显示;1,正常显示
//size:选择字体 16/12
void OLED_ShowChar(u8 x,u8 y,u8 chr,u8 Char_Size)
{
unsigned char c=0,i=0;
c=chr-' ';//得到偏移后的值
if(x>Max_Column-1){x=0;y=y+2;}
if(Char_Size ==16)
{
OLED_Set_Pos(x,y);
for(i=0;i<8;i++)
OLED_WR_Byte(F8X16[c*16+i],OLED_DATA);
OLED_Set_Pos(x,y+1);
for(i=0;i<8;i++)
OLED_WR_Byte(F8X16[c*16+i+8],OLED_DATA);
}
else {
OLED_Set_Pos(x,y);
for(i=0;i<6;i++)
OLED_WR_Byte(F6x8[c],OLED_DATA);
}
}
//m^n函数
u32 oled_pow(u8 m,u8 n)
{
u32 result=1;
while(n--)result*=m;
return result;
}
//显示2个数字
//x,y :起点坐标
//len :数字的位数
//size:字体大小
//mode:模式 0,填充模式;1,叠加模式
//num:数值(0~4294967295);
void OLED_ShowNum(u8 x,u8 y,u32 num,u8 len,u8 size2)
{
u8 t,temp;
u8 enshow=0;
for(t=0;t<len;t++)
{
temp=(num/oled_pow(10,len-t-1))%10;
if(enshow==0&&t<(len-1))
{
if(temp==0)
{
OLED_ShowChar(x+(size2/2)*t,y,' ',size2);
continue;
}else enshow=1;
}
OLED_ShowChar(x+(size2/2)*t,y,temp+'0',size2);
}
}
//显示一个字符号串
void OLED_ShowString(u8 x,u8 y,u8 *chr,u8 Char_Size)
{
unsigned char j=0;
while (chr[j]!='\0')
{ OLED_ShowChar(x,y,chr[j],Char_Size);
x+=8;
if(x>120){x=0;y+=2;}
j++;
}
}
//显示汉字
void OLED_ShowCHinese(u8 x,u8 y,u8 no)
{
u8 t,adder=0;
OLED_Set_Pos(x,y);
for(t=0;t<16;t++)
{
OLED_WR_Byte(Hzk[2*no][t],OLED_DATA);
adder+=1;
}
OLED_Set_Pos(x,y+1);
for(t=0;t<16;t++)
{
OLED_WR_Byte(Hzk[2*no+1][t],OLED_DATA);
adder+=1;
}
}
/***********功能描述:显示显示BMP图片128×64起始点坐标(x,y),x的范围0~127,y为页的范围0~7*****************/
void OLED_DrawBMP(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++)
{
OLED_Set_Pos(x0,y);
for(x=x0;x<x1;x++)
{
OLED_WR_Byte(BMP[j++],OLED_DATA);
}
}
}
//初始化SSD1306
void OLED_Init(void)
{
/* Wait for minimum time required between transfers. */
R_BSP_SoftwareDelay(800, BSP_DELAY_UNITS_MICROSECONDS);
OLED_WR_Byte(0xAE,OLED_CMD);//--display off
OLED_WR_Byte(0x00,OLED_CMD);//---set low column address
OLED_WR_Byte(0x10,OLED_CMD);//---set high column address
OLED_WR_Byte(0x40,OLED_CMD);//--set start line address
OLED_WR_Byte(0xB0,OLED_CMD);//--set page address
OLED_WR_Byte(0x81,OLED_CMD); // contract control
OLED_WR_Byte(0xFF,OLED_CMD);//--128
OLED_WR_Byte(0xA1,OLED_CMD);//set segment remap
OLED_WR_Byte(0xA6,OLED_CMD);//--normal / reverse
OLED_WR_Byte(0xA8,OLED_CMD);//--set multiplex ratio(1 to 64)
OLED_WR_Byte(0x3F,OLED_CMD);//--1/32 duty
OLED_WR_Byte(0xC8,OLED_CMD);//Com scan direction
OLED_WR_Byte(0xD3,OLED_CMD);//-set display offset
OLED_WR_Byte(0x00,OLED_CMD);//
OLED_WR_Byte(0xD5,OLED_CMD);//set osc division
OLED_WR_Byte(0x80,OLED_CMD);//
OLED_WR_Byte(0xD8,OLED_CMD);//set area color mode off
OLED_WR_Byte(0x05,OLED_CMD);//
OLED_WR_Byte(0xD9,OLED_CMD);//Set Pre-Charge Period
OLED_WR_Byte(0xF1,OLED_CMD);//
OLED_WR_Byte(0xDA,OLED_CMD);//set com pin configuartion
OLED_WR_Byte(0x12,OLED_CMD);//
OLED_WR_Byte(0xDB,OLED_CMD);//set Vcomh
OLED_WR_Byte(0x30,OLED_CMD);//
OLED_WR_Byte(0x8D,OLED_CMD);//set charge pump enable
OLED_WR_Byte(0x14,OLED_CMD);//
OLED_WR_Byte(0xAF,OLED_CMD);//--turn on oled panel
}
电机pwm设置
小车上电初始化时,开发板上的蜂鸣器会响一秒,随后等待指令的发出,并不断的采集周围环境的信息,例如温度、湿度、是否有火。
void hal_entry(void)
{
/* TODO: add your own code here */
bsp_io_level_t state;
int dht11_time=0,fire;
err = R_SCI_I2C_Open(&g_sci6_i2c_ctrl, &g_sci6_i2c_cfg);
/* Handle any errors. This function should be defined by the user. */
assert(FSP_SUCCESS == err);
//err = FSP_SUCCESS;
//打开串口
err = R_SCI_UART_Open(&g_uart4_ctrl, &g_uart4_cfg);
assert(FSP_SUCCESS == err);
//打开蓝牙的串口3
err = R_SCI_UART_Open(&g_uart3_ctrl, &g_uart3_cfg);
assert(FSP_SUCCESS == err);
pwm_init();
OLED_Init(); //oled初始化
OLED_Clear();
R_IOPORT_PinWrite(&g_ioport_ctrl, BSP_IO_PORT_06_PIN_05, BSP_IO_LEVEL_HIGH);
R_BSP_SoftwareDelay(1, BSP_DELAY_UNITS_SECONDS); //延时 1 秒
u2_printf("ra6m5_ok");
while(1)
{
R_IOPORT_PinWrite(&g_ioport_ctrl, BSP_IO_PORT_06_PIN_05, BSP_IO_LEVEL_LOW);
R_IOPORT_PinRead(&g_ioport_ctrl,BSP_IO_PORT_03_PIN_02, &state);
OLED_ShowCHinese(0,4,12); //是否有火
OLED_ShowCHinese(16,4,13);
OLED_ShowCHinese(32,4,14);
OLED_ShowCHinese(48,4,15);
OLED_ShowCHinese(64,4,13);
if(state == BSP_IO_LEVEL_LOW)
{
OLED_ShowCHinese(64,4,12);
R_BSP_SoftwareDelay(20, BSP_DELAY_UNITS_MILLISECONDS); //延时20
}
if(dht11_flag == 1){
u2_printf("t,h:");
u2_printf(str_dht11);
dht11_flag=0;
}
if(dht11_time%5 == 0)
{
DHT11_Read();
sprintf(str_dht11,"%d,%d",temp_integer,humdity_integer);
OLED_ShowNum(48,2,temp_integer,3,16);
//OLED_ShowNum(0,4,dht11_time,3,16);
}
if(dht11_time >500)
{
dht11_time=0;
}
}
|
|