标题云家居文档
一、概述
1.1主控芯片
Stm32f103c8
1.1.1基本参数
类别:集成电路(IC)
家庭:嵌入式-微控制器
总线宽度:32-位
速度:72MHz
外围设备:DMA,电机控制PWM,PWM,温度传感器
输入/输出数:37
程序存储器容量:64KB (64K x 8)
程序存储器类型:FLASH
RAM容量:20K x 8
电压-电源(Vcc/Vdd):2 V ~ 3.6 V
数据转换器:A/D 10x12b
振荡器型:内部
1.1.2其他参数
工作温度:-40°C ~ 85°C
封装/外壳:48-LQFP
包装:托盘
1.2外围模块资源清单
模块 驱动芯片 相关引脚 寄存器使用
LED1、LED2、LED3 \ PB11—LED1(1亮)
PB14—LED2(1亮)
PA11—LED1(1亮) GPIOA、GPIOB
KEY1、KEY2、KEY3 \ PA0—KEY1(1代表按键动作)
PA8—KEY2(0代表按键动作)
PB10—KEY3(0代表按键动作) GPIOA、GPIOB
继电器 \ PB1 GPIOB
全彩RGB灯珠 P9813 PB9-----------RGB_DATA
PB8-----------RGB_CLK GPIOB
wifi模块 Esp8266 PA2-----------USART2_TX
PA3-----------USART2_RX GPIOA、USART2
直流电机 L9110s PB4—motorA(tim3ch1)
PB5—motorB(tim3ch2) GPIOB、TIM3
步进电机 Lb1936 PA7–A相
PA6–A反相
PA5–B相
PA4–B反相 GPIOA、TIM1
温湿度传感器 dht11 PB3–DHT11_DATA GPIOB、SysTick
oled屏 Sh1106 复位:OLED_RES-----------PB6
片选:OLED_CS-----------PB7
数据、命令:OLED_D/C-----------PB12
时钟线:OLED_SCLK-----------PB13
输入OLED_SDIN-----------PB15
时钟线PB13和输入PB15用作SPI复用功能 GPIOB、SPI2
红外接收头 \ PA1—TIM2_CH2 GPIOA、TIM2
1.3一张图了解一下
1.4 编程流程图了解一下
二、各模块的使用
下载接口连接方式
简单元器件如LED、KEY、继电器不赘述,这里提到的模块有wifi模块、OLED屏、温湿度传感器、rgb全彩灯珠、小型步进电机和直流电机。
2.1 wifi模块:esp8266
2.1.1 初始化(AT固件烧录)
Esp8266可以使用串口通信与pc端交换数据,使用到引脚VCC、GND、UTXD、URXD。
第一步:
打开烧录软件
下载的固件在网站上下载,
注意:要烧录的文件所放的路径不要太深。
本模块采用的是安信可出厂默认 AT固件,固件下载地址如下:
http://wiki.ai-thinker.com/esp8266/sdk
第二步
点击start开始下载,必要时进行复位,load模式。
下载成功后,打开串口调试助手,波特率设置为76800,然后复位,得到如下信息:
2.1.2 常用指令
相关手册:
波特率改为115200
指令1:发送 AT测试指令:AT\r\n
回复
AT
OK
指令2:WIFI 模式设置指令:AT+CWMODE_DEF=1
回复
AT+CWMODE_DEF=1
OK
注:station模式(客户端模式)
在此模式下,模块相当于一个客户端,可以链接到其他路由器发出的 WIFI 信号。
softAP 模式(软路由模式)
在此模式下,模块本身相当于一个路由器,其他设备可以链接到该模块发送的信号。
station+softAP 模式(混合模式)
在此模式下,模块可在与其他设备链接的同时充当路由器,结合上面两种模式的综合。
指令3:WIFI 模式查询指令:AT+CWMODE?
回复
AT+CWMODE?
+CWMODE:1 //1:station 模式 2:softAP 模式 3:station+softAP 模式
OK
指令4:连接 AP 指令:AT+CWJAP_DEF=”mwh”,”123123123”
回复
AT+CWJAP_DEF=“mwh”,“123123123”
WIFI CONNECTED
WIFI GOT IP
OK
注:本设置会保存到 flsh system parameter 区域
指令5:断开与 AP连接指令:AT+CWQAP
回复
AT+CWQAP
OK
WIFI DISCONNECT
指令6:WIFI 模式设置指令:AT+CWMODE_DEF=2
回复
AT+CWMODE=2
OK
指令7:配置 softAP 参数指令:AT+CWSAP_DEF=“mwh_esp8266”,“123123123”,5,3
回复
AT+CWSAP_DEF=“mwh_esp8266”,“123123123”,5,3
OK
注:本设置会保存到 flsh system parameter 区域
指令8:查询连接到 ESP8266 softAP 的 stations 信息指令:AT+CWLIF
回复
AT+CWLIF
192.168.4.2,b8:ee:65:e0:5f:34
OK
2.1.3 STA模式连接 TCP Server 透传
TCP(Transmission Control Protocol,传输控制协议)是基于连接的协议,也就是说,在正式收发数据前,必须和对方建立可靠的连接。一个 TCP 连接必须要经过三次“握手”才能建立起。
TCP 协议能为应用程序提供可靠的通信连接,使一台计算机发出的字节流无差错地发往网络上的其他计算机,对可靠性要求高的数据通信系统往往使用 TCP 协议传输数据。
注:指令后面一般要加\r\n
1.配置 WiFi 模组工作模式为单 STA模式,并把配置保存在 flash
指令:AT+CWMODE_DEF=1
响应:OK
-
连接路由器,保存在 flash
指令:AT+CWJAP_DEF=“118”,“88826131”
响应:OK -
查询 ESP8266 IP 地址
指令:AT+CIFSR
响应:+CIFSR:STAIP,“192.168.0.108”
+CIFSR:STAMAC,“b4:e6:2d:53:ee:04” -
连接 TCP 服务器
指令:AT+CIPSTART=“TCP”,“192.168.0.106”,8080
响应:OK
5.开启透传模式传输数据
指令:AT+CIPMODE=1
响应:OK
- 发送数据
指令:AT+CIPSEND
响应:>
7.结束穿透模式
指令:+++
响应:
注:后面不用加\r\n
- 断开与 TCP 服务器连接
指令:AT+CIPCLOSE
响应:CLOSED
OK
9.断开与 AP 的连接
指令:AT+CWQAP
响应:OK
另:开启服务器模拟
A:开启服务器
B:查询IP
打开CMD
快捷键(win+R),输入cmd
另:开启服务器助手
2.1.4 http协议网络请求文件(略)
简单请求语句:
GET \test\test.html
2.2 OLED屏
2.2.1 简介
淘宝卖品:
像素:长128,宽64
资料:
产品参数:
1、无需背光、显示单元能自发光
2、分辨率:12864
3、可视角度大:> 160°
4、支持众多控制芯片:全面兼容Arduino、51系列、MSP430系列、STM32/、CSR芯片等
5、低功耗:全屏点亮时0.08W,正常全屏显示汉字0.06W (远低于TFT、LCD等技术)
6、宽电压支持:无需任何修改,直接支持3V~5V直流
7、工作温度: -40°C~70°C
8、模块体积(长宽厚): 27.3MM27.8MM*3.7MM
9、I0口占用少:采用SPI或1IC通信方式,最多只要4个IO口就能驱动
10、驱动芯片: SSD1306
11、无字库:用取模软件取字,显示什么取什么.so easy!
接口定义:
1> GND(电源地)
2> VCC(电源正3.3~5V)
3> D0(SPI接口时为SPI时钟线,IC接口时为IC时钟线)
4> D1(SPI接口时为SPI数据线,IC接口时为IIC数据线)
5> RES(OLED复位,OLED 在上电后需要做一次复位)
6> DC(SPI数据/命令选择脚,IC接口时用来设IC地址)
7> CS(OLEDSPI片选,底电平有效,如不想用必须接地)
重要说明: OLED 显示屏不同于LCD; OLED 是自发光的;所以没有背光,在只加电源的情况话屏不会有任何反应;必须有程序正确操作才会有显示,这点大家 需要注意
2.2.2 程序驱动
可以下载相关手册
OLED显存:SSD1306
<1>原理图
由原理图可知
有五个引脚需要用到:
复位:OLED_RES-----------PB6(推挽输出)
片选:OLED_CS-----------PB7(推挽输出)
数据、命令:OLED_D/C-----------PB12(推挽输出)
时钟线:OLED_SCLK-----------PB13(推挽输出)
输入:OLED_SDIN-----------PB15(推挽输出)
注意:时钟线PB13和输入PB15用作SPI复用功能,这里不用初始化,否则出错
<2>简单描述
设置为4线spi
SSD1306 的显存总共为 12864bit 大小, SSD1306 将这些显存分为了 8 页,SSD1306 的每页包含了 128个字节,总共 8 页,这样刚好是 12864 的点阵大小。》
<3>基本命令
命令 0X81,用于设置对比度的,这个命令包含了两个字节,第一个 0X81 为命令,随后发送的一个字节为要设置的对比度的值。这个值设置得越大屏幕就越亮。
命令 0XAE/0XAF。0XAE 为关闭显示命令;0XAF为开启显示命令。
命令 0X8D,该指令也包含 2 个字节,第一个为命令字,第二个为设置值,第二个字节的 BIT2 表示电荷泵的开关状态,该位为 1,则开启电荷泵,为 0 则关闭。在模块初始化的时候,必须要 开启,否则是看不到屏幕显示的。
命令 0XB0~B7,该命令用于设置页地址,其低三位的值对应着 GRAM 的页地址。
命令 0X00~0F,该命令用于设置列地址低四位,其低四位的值对应着 GRAM 的列地址低四位。
命令 0X10~1F,该命令用于设置列地址高四位,其低四位的值对应着 GRAM 的列地址高四位。
<4>spi程序
#include “spi.h”
/*
函数功能:SPI2初始化
*/
void SpiInit(void)
{
//OLED_SCK—PB13—复用成SPI2_SCK
//OLED_SDIN(MOSI)—PB15—复用成SPI2_MOSI
//GPIO口初始化
RCC->APB2ENR |=0x01<<3;
GPIOB->CRH &=~(0x0F<<20|0x0F<<28);
GPIOB->CRH |=(0x0B<<20|0x0B<<28);
//SPI2初始化
RCC->APB1ENR |=0x01<<14;
SPI2->CR1=0;//寄存器清零
/*
选择“双线单向”模式
禁止CRC计算
使用8位数据帧格式进行发送/接收
全双工(发送和接收)
先发送MSB
波特率控制--36M/2=18M
MODE0
*/
SPI2->CR1 |=0x01<<2;//主模式
SPI2->CR1 |=0x03<<8;//软件从模式管理
SPI2->CR1 |=0x01<<6;//开启SPI
}
/*
函数功能:主机给从机发送一个字节数据
参数说明:带发送的数据
返回值:无
注意事项:MODE0/3
/
u8 SpiSendByte(u8 data)
{
while(!(SPI2->SR&(0x01<<1)));//等待发送缓冲为空
SPI2->DR=data;
while(!(SPI2->SR&(0x01<<0)));//等待接收缓冲为空
return SPI2->DR;
}
<5>初始化操作
/
函数功能:引脚初始化
参数:无
返回值:空
*/
//复位:OLED_RES-----------PB6(推挽输出)
//片选:OLED_CS-----------PB7(推挽输出)
//数据、命令:OLED_D/C-----------PB12(推挽输出)
//时钟线:OLED_SCLK-----------PB13(推挽输出)
//输入:OLED_SDIN-----------PB15(推挽输出)
//注意://时钟线PB13和输入PB15用作SPI复用功能,这里不用初始化,否则出错
void OledPin_init(void)
{
RCC->APB2ENR |=0x01<<3;
GPIOB->CRL &=~(0x0f<<24);
GPIOB->CRL |=0x01<<24;
GPIOB->CRL &=~(0x0f<<28);
GPIOB->CRL |=0x01<<28;
GPIOB->CRH &=~(0x0f<<16);
GPIOB->CRH |=0x01<<16;//PB12
// GPIOB->CRH &=~(0x0f<<20);
// GPIOB->CRH |=0x03<<20;//PB13
//
// GPIOB->CRH &=~(0x0f<<28);
// GPIOB->CRH |=0x03<<28;//PB15
OLED_CS=1;//不片选
OLED_RES=1;//不复位
}
/*
函数功能:OLED写入一个命令
参数:命令
返回值:空
*/
void OledSendCmd(u8 cmd)
{
OLED_CS=0;
OLED_DC=0;
SpiSendByte(cmd);
OLED_CS=1;//
}
/*
函数功能:OLED写入一个数据
参数:命令
返回值:空
*/
void OledSendData(u8 data)
{
OLED_CS=0;
OLED_DC=1;
SpiSendByte(data);
OLED_CS=1;//
}
///*
//函数功能:OLED初始化
//参数:无
//返回值:空
//*/
void OledStartInit(void)
{
SpiInit();
OledPin_init();//引脚初始化
OLED_RES=1;
Delay(5000);
OLED_RES=0;
Delay(5000);
OLED_RES=1;
Delay(5000);
OledSendCmd(0xAE); //关闭显示
OledSendCmd(0xD5); //设置时钟分频因子,震荡频率
OledSendCmd(80); //[3:0],分频因子;[7:4],震荡频率
OledSendCmd(0xA8); //设置驱动路数
OledSendCmd(0X3F); //默认0X3F(1/64)
OledSendCmd(0xD3); //设置显示偏移
OledSendCmd(0X00); //默认为0
OledSendCmd(0x40); //设置显示开始行 [5:0],行数.
OledSendCmd(0x8D); //电荷泵设置
OledSendCmd(0x14); //bit2,开启/关闭
OledSendCmd(0x20); //设置内存地址模式
OledSendCmd(0x02); //[1:0],00,列地址模式;01,行地址模式;10,页地址模式;默认10;
OledSendCmd(0xA1); //段重定义设置,bit0:0,0->0;1,0->127;
OledSendCmd(0xC8); //设置COM扫描方向;bit3:0,普通模式;1,重定义模式 COM[N-1]->COM0;N:驱动路数
OledSendCmd(0xDA); //设置COM硬件引脚配置
OledSendCmd(0x12); //[5:4]配置
OledSendCmd(0x81); //对比度设置
OledSendCmd(0xEF); //1~255;默认0X7F (亮度设置,越大越亮)
OledSendCmd(0xD9); //设置预充电周期
OledSendCmd(0xf1); //[3:0],PHASE 1;[7:4],PHASE 2;
OledSendCmd(0xDB); //设置VCOMH 电压倍率
OledSendCmd(0x30); //[6:4] 000,0.65*vcc;001,0.77*vcc;011,0.83*vcc;
OledSendCmd(0xA4); //全局显示开启;bit0:1,开启;0,关闭;(白屏/黑屏)
OledSendCmd(0xA6); //设置显示方式;bit0:1,反相显示;0,正常显示
OledSendCmd(0xAF); //开启显示,0xae代表不显示
OledClear();
}
/*
函数功能:清屏
参数:无
返回值:空
/
void OledClear(void)
{
u8 i,n;
for(i=0;i<8;i++)
{
OledSendCmd (0xb0+i); //设置页地址(0~7)
OledSendCmd (0x02); //设置显示位置—列低地址
OledSendCmd (0x10); //设置显示位置—列高地址
for(n=0; n<128; n++)
{
OledSendData(0);
}
}
}
<6>显示字符串(暂无图片)程序
注:显示屏显示特点是横的方向分为0127列,每列为一个像素点跨度,竖的方向分为07页,每页为8个像素点跨度。每次显示为8个像素点,数据是一个字节,当显示完一个字节后,系统的显示指针自动指向下一个列位置,但不会指向下一个页。扫描放向为先从左往右,再从上往下。
/
函数功能:设置要显示的单元?(最小单元是竖着的8个元素点)
8个页,64列
参数:y为页数,范围(07),x是列数(范围0127)
返回值:空
*/
void OledSetPosition(u8 x,u8 y)
{
OledSendCmd(0xb0+y);
OledSendCmd(x%16+1);//设置列低地址(命令范围0x00~0x0f)
OledSendCmd(x/16+0x10);//设置列高地址(命令范围0x10~0x1f)
}
/*
函数功能:显示字体
参数:方位和字符
返回值:空
/
void OledDisplayChar16(u8 x,u8 y,u8 ch)
{
u8 num,data,i,j;
num=ch-’ ';
for(j=0;j<=1;j++)
{
OledSetPosition(x,y+j);
for(i=0;i<=7;i++)
{
data=OledFont16[num16+i+j8];
OledSendData(data);
}
}
}
/
函数功能:显示字符串
参数:方位和字符串
返回值:空
*/
void OledDisplayStr16(u8 x,u8 y,u8 *str_p)
{
u8 x0,y0;
x0=x;
y0=y;
u16 i=0;
while((*str_p)!=’\0’)
{
if((x0+8)>=127)
{
y0=y+2;
x0=8;
}
OledDisplayChar16(x0,y0,*str_p);
x0=x0+8;
str_p++;
}
}
2.3 DHT11温湿度传感器
2.3.1 简介
<1>淘宝卖品
产品
1、可以检测网围环境的湿度和温度
2、传感器采用DHT111
3、输出形式数字输出
4、设有固定螺栓孔,方便安装
5、小板PCB
6、电源指示灯(红色)
7、数字信号输出1
8、数据端口带上拉电阻:
9、带3mm固定螺丝孔,方便安装1
10、送杜邦线
参数
温度分辨率: 1℃elea
温度精度: ±2℃ea
温度检测范围: 0℃~50℃
湿度分辨率: 1%RH
湿度精度: ±5%PH (0-50℃)
湿度检測范围: 20%RH 90%H (2℃)
工作电压: 3.3V5.5 V
推荐存储环境:温度: 10℃-40℃湿度: 60%RH以下
重量: 8g
尺寸: 3.2am* 1.4m
接线
VCC外接3.3V-5V202
GND外接GND
DO小板开关数字量输出接口接单片机IO口
<2>参考手册资料
DHT11产品概述
DHT11数字温湿度传感器是一款含有已校准数字信号输出的温湿度复合传感器。它应用专用的数字模块采集技术和温湿度传感技术,确保产品具有极高的可靠性与卓越的长期稳定性。传感器包括一个电阻式感湿元件和一个NTC测温元件,并与一个高性能8位单片机相连接。因此该产品具有品质卓越、超快响应、抗干扰能力强、性价比极高等优点。每个DHT11传感器都在极为精确的湿度校验室中进行校准。校准系数以程序的形式储存在OTP内存中,传感器内部在检测信号的处理过程中要调用这些校准系数。单线制串行接口,使系统集成变得简易快捷。超小的体积、极低的功耗,信号传输距离可达20米以上,使其成为各类应用甚至最为苛刻的应用场合的最佳选则。产品为 4 针单排引脚封装。连接方便,特殊封装形式可根据用户需求而提供。
串行接口 (单线双向)
DATA 用于微处理器与 DHT11之间的通讯和同步次通讯时间4ms左右,数据分小数部分和整数部分,具体部分用于以后扩展,现读出为零.操作流程如下:一次完整的数据传输为40bit,高位先出。
数据格式:8bit湿度整数数据+8bit湿度小数数据+8bi温度整数数据+8bit温度小数数据+8bit校验和。
数据传送正确时,校验和数据等于8bit湿度整数数温度整数数据+8bit温度小数数据”所得结果的末8位。
时序图
2.3.1 模块驱动程序
<1>原理图及其引脚接线
只有一根线与MCU相连
数据线与PB3引脚相连
PB3引脚设置为开漏输出
#include “dht11.h”
#include “systick.h”
#include “stdio.h”
#include “delay.h”
/*
需优化:温湿度传感器上电后需等待一秒后才能正常发数据
/
/
延时说明:time=1000000时,延时500ms
time=100000时,延时50ms
time=10000时,延时约6.6ms
*/
void Dht11Delay(u16 t)
{
u16 i;
u32 time;
for(i=1;i<=t;i++)
{
time=100000;
while(time–);
}
}
/*
函数功能:温湿度传感器初始化(DHT11)
参数:无
返回值:空
注:
数据线与PB3引脚相连
PB3引脚设置为开漏输出
*/
void Dht11Pin_init(void)
{
u32 i,j,timeout=0;
//Dht11Delay(20);
RCC->APB2ENR |=0x01<<3;
GPIOB->CRL &=~(0x0f<<12);
GPIOB->CRL |=0x07<<12;
RCC->APB2ENR |=0x01<<0;
AFIO->MAPR &=~(0x07<<24);
AFIO->MAPR |=0x02<<24;//关闭JTAG-DP,启用SW-DP;
GPIOB->ODR |=0x01<<3;
}
/*
函数功能:MCU发送开始信号
参数:无
返回值:空
*/
void Dht11SendStart(void)
{
// u32 delay_time;
TEMPE_OUT=1;
Dht11Delay(1);
TEMPE_OUT=0;
Delay_ms(18);
TEMPE_OUT=1;
}
/*
函数功能:检测传感器响应
参数:无
返回值:1代表成功,0代表失败
*/
//注,使用SystickInterStartUs()函数作超时,又使用SystickDelayMs()作延时,会出现错误
u8 Dht11Answer(void)
{
u32 timeout=100000; //超时时间:50ms
TEMPE_OUT=1;//拉高数据线
while (timeout && TEMPE_STA)
{
timeout–;
}
if(timeout!=0)
{
//printf(“OK\r\n”);
timeout=100000;
if(TEMPE_STA0)
{
timeout–;
while(TEMPE_STA0 && timeout);
}
timeout=100000;
if(TEMPE_STA==1)
{
timeout--;
while(TEMPE_STA==1 && timeout);
}
return 1;
}
else
{
//printf("FAIL\r\n");
return 0;
}
}
/*
函数功能:接收一个字节数据
参数:空
返回值:数据
*/
u8 Dht11GetByte(void)
{
u8 data=0;
u32 cnt[8],i,timeout;
for(i=0;i<=7;i++)
{
timeout=100000;
if(TEMPE_STA==0)
{
timeout--;
while(TEMPE_STA==0 && timeout);
}
timeout=100000;
if(TEMPE_STA==1)
{
timeout--;
Syscnt_start();
while(TEMPE_STA==1 && timeout);
cnt[i]=Syscnt_end();
}
}
for(i=0;i<=7;i++)
{
if(cnt[i]>=55 && cnt[i]<=85)
{
data |=0x01<<(7-i);
}
//printf("%d ",cnt[i]);
}
//printf("\r\ndata:%d\r\n",data);
return data;
}
/*
函数功能:做一次采样
参数:无
返回值:0:成功;1:无响应 2:校验失败
*/
TYPE_TEMPEDATA tempeData;
TYPE_TEMPEDATA tempeData={0};
u8 Dht11Updata(void)
{
u8 data1,data2,data3,data4,data5;
Dht11SendStart();
if(Dht11Answer()==1)
{
TEMPE_OUT=1;//拉高数据线
tempeData.humi_int=Dht11GetByte();
tempeData.humi_dec=Dht11GetByte();
tempeData.temp_int=Dht11GetByte();
tempeData.temp_dec=Dht11GetByte();
tempeData.jiaoyan=Dht11GetByte();
//printf("%d %d %d %d %d\r\n",tempeData.humi_int,tempeData.humi_dec,tempeData.temp_int,tempeData.temp_dec,tempeData.jiaoyan);
tempeData.humi=tempeData.humi_int+(float)tempeData.humi_dec/255;
tempeData.temp=tempeData.temp_int+(float)tempeData.temp_dec/255;
if(tempeData.jiaoyan==(tempeData.humi_int+tempeData.humi_dec+tempeData.temp_int+tempeData.temp_dec))
{
tempeData.mark=1;
}
else
{
tempeData.mark=0;
}
if(tempeData.mark==0)
{
return 2;
}
}
else
{
return 1;
}
return 0;
}
2.4 RGB彩灯
2.4.1 简介
<1>淘宝卖品
驱动芯片为p8913
手册资料
P9813 是一款全彩点光源 LED 驱动芯片,采用 CMOS工艺,提供三路恒流驱动及 256级灰度调制输出。采用双线传输方式(DATA与 CLK),内建再生,可提升传输距离。用于驱动显示灯光变换、各式字变换、彩色动漫图案。根据不同控制器和客户不同形式要求,进行脱机或联机运行。 本产品具有性能优良,可视效果分明,级联方式简单;数据传输稳定、抗干扰能力强等特点。 提供SOP14(P9813S14)封装、DIP14(P9813D14)封装、SSOP16(P9813SS16)
<2>原理图及其引脚接线
与MCU相连的引脚为
(PB9-----------RGB_DATA)
(PB8-----------RGB_CLK)
与MCU的通信方式为单工串行通信
<3>时序
有个疑问:编程时,数据在Cin下降延时打入似乎更有用
#include “p9813led.h”
#include “delay.h”
/*
疑问:切换灯颜色的时候>2s时效果好??
*/
/*
函数功能:管脚初始化
参数:无
返回值:空
说明:
(PB9-----------RGB_DATA)
(PB8-----------RGB_CLK)
*/
void RgbPin_init(void)
{
//LED1配置
RCC->APB2ENR |=0x01<<3;
GPIOB->CRH &=~(0x0f<<4);
GPIOB->CRH |=0x01<<4;
GPIOB->CRH &=~(0x0f<<0);
GPIOB->CRH |=0x01<<0;
}
void RgbStartInit(void)
{
u32 i;
//RgbPin_init();
RGB_CLK=1;
RGB_DATA=0;
Delay(20000);
for(i=0;i<=40;i++)
{
RGB_CLK=1;
Delay(5000);
RGB_CLK=0;
Delay(5000);
}
}
/*
函数功能:点亮RGB灯珠
参数:无
返回值:空
注意:顺序为蓝绿红,校验位与原位相反
//data=0xf300ff00;//绿
//data=0xcfff0000;//蓝
//data=0xfc0000ff;//红
*/
void LightRgb(u8 red,u8 green,u8 blue)
{
RgbStartInit();
u32 data=0;
u32 i;
data |=0x01<<31;
data |=0x01<<30;
if((blue & 0x80)==0)
{
data |=0x01<<29;
}
if((blue & 0x40)==0)
{
data |=0x01<<28;
}
if((green & 0x80)==0)
{
data |=0x01<<27;
}
if((green & 0x40)==0)
{
data |=0x01<<26;
}
if((red & 0x80)==0)
{
data |=0x01<<25;
}
if((red & 0x40)==0)
{
data |=0x01<<24;
}
data=data | (blue<<16);
data=data | (green<<8);
data=data | (red<<0);
//32位灰度数据
SendDataToRgb(data);
}
/*
函数功能:给灯发送数据
参数:u32 灰度数据
返回值:空
*/
void SendDataToRgb(u32 data)
{
u32 i;
RGB_CLK=0;
for(i=0;i<=31;i++)
{
RGB_CLK=1;
if(((data<<i) & 0x80000000)!=0)
{
RGB_DATA=1;
}
else
{
RGB_DATA=0;
}
Delay(5000);
RGB_CLK=0;
Delay(5000);
}
//printf("\r\n");//一定要开启中断USART1才能调用,不然会灯不会变色
}
/*
函数功能:关灯
*/
void TurnOffRgb(void)
{
RgbStartInit();
SendDataToRgb(0xff000000);
}
2.5 直流电机
2.5.1 驱动芯片L9110
参考资料、手册
2.5.2原理图及其引脚
MOTOR-B脚配置(PB4)
MOTOR-A脚配置(PB5)
2.5.3 驱动程序
#include “motor.h”
/*
说明:PWM控制直流电机,使用定时器3的比较输出通道1控制
MOTOR-B脚配置(PB4)
MOTOR-A脚配置(PB5)
*/
/*
函数功能:PWM波控制电机
参数:psc、ARR和CCR1的值(16位),范围(0~65536),ch选择通道,1代表1通道,
返回值:空
注:
PB4—motorA—tim3ch1
PB5—motorB—tim3ch2
规定:motorA=1,motorB=0时,电机正转
则motorA=0,motorB=1时,电机正转
time3----72MHz
*/
void timer3Ch1Out_init(u16 psc,u16 arr,u16 ccr1,u16 ccr2)//周期单位us peroid<65536/2
{
RCC->APB2ENR |=0x01<<3;
GPIOB->CRL &=~(0x0f<<16);
GPIOB->CRL |=0x09<<16;
GPIOB->CRL &=~(0x0f<<20);
GPIOB->CRL |=0x09<<20;
//GPIOB->ODR &=~(0x01<<5);
//GPIOB->ODR |=0x01<<5;
RCC->APB2ENR |=0x01<<0;//注意复用功能使能,很容易忽略
AFIO->MAPR &=~(0x7<<24);
AFIO->MAPR |=0x02<<24;
AFIO->MAPR &=~(0x03<<10);
AFIO->MAPR |=0x02<<10;//复用功能
RCC->APB1ENR |= 0x01<<1;//
TIM3->CR1=0;
/*
无缓冲
向上计数
循环模式
多请求源
允许事件更新
*/
TIM3->PSC = psc-1;
TIM3->ARR = arr-1;
//通道1配置
TIM3->CCR1 =ccr1-1;
TIM1->SMCR &=~(0x03<<0);//关闭从模式
TIM3->CCMR1 &=~(0x03<<0);//配置为比较输出
TIM3->CCMR1 &=~(0x03<<2);//无缓冲
//TIM3->CCMR1 |=0x01<<3;
TIM3->CCMR1 &=~(0x07<<4);
TIM3->CCMR1 |=0x06<<4;//PWM1模式
TIM3->CCER &=~(0x03<<0);
//TIM3->CCER |=0x01<<0;//通道1使能,高电平有效(暂时关闭)
//通道2配置
TIM3->CCR2 =ccr2-1;
//TIM1->SMCR &=~(0x03<<0);//关闭从模式
TIM3->CCMR1 &=~(0x03<<8);//配置为比较输出
TIM3->CCMR1 &=~(0x03<<10);//无缓冲
//TIM3->CCMR1 |=0x01<<3;
TIM3->CCMR1 &=~(0x07<<12);
TIM3->CCMR1 |=0x06<<12;//PWM1模式
TIM3->CCER &=~(0x03<<4);
//TIM3->CCER |=0x01<<4;//通道2使能,高电平有效(暂时关闭)
TIM3->EGR |=0x01<<0;//开启一次更新事件,使计数器清零,预分频和重载器赋值
TIM3->SR &=~(0x01<<0);
while(TIM3->SR & 0x01){};//清除标志位
//TIM3->CR1 |=0x01<<0;//计数器开启(初始化没有开启)
}
//正转开启
void MotorPwm_zhen_on(u32 peroid,float zkb)
{
TIM3->PSC =72-1;
TIM3->ARR = peroid-1;
TIM3->CCR1 =peroidzkb;
TIM3->CCER &=~(0x01<<4);//输出2关闭
TIM3->CCER |=0x01<<0;//输出1开启
TIM3->CR1 |=0x01<<0;//开计数器
}
//反转开启
void MotorPwm_fan_on(u32 peroid,float zkb)
{
TIM3->PSC =72-1;
TIM3->ARR = peroid-1;
TIM3->CCR2 =peroidzkb;
TIM3->CCER &=~(0x01<<0);//输出1关闭
TIM3->CCER |=0x01<<4;//输出2开启
TIM3->CR1 |=0x01<<0;//开计数器
}
void MotorPwm_off(void)
{
TIM3->CCER &=~(0x01<<0);//输出1关闭
TIM3->CCER &=~(0x01<<4);//输出2关闭
TIM3->CR1 &=~(0x01<<0);//关计数器
}
2.6 步进电机
2.6.1 驱动芯片