stm32系列基于专为要求高性能、低成本、低功耗的嵌入式应用专门设计的arm cortex-m3内核,其中stm32f系列有:stm32f103“增强型”系列stm32f101“基本型”系列stm32f105、stm32f107“互联型”系列,增强型系列时钟频率达到72mhz,是同类产品中性能最高的产品;基本型时钟频率为36mhz,以16位产品的价格得到比16位产品大幅提升的性能,是32位产品用户的最佳选择。两个系列都内置32k到128k的闪存,不同的是sram的最大容量和外设接口的组合。时钟频率72mhz时,从闪存执行代码,stm32功耗36ma,相当于0.5ma/mhz。
基于stm32实现dmx512协议发送与接收
dmx512数据协议是美国舞台灯光协会(usitt)于1990年发布的一种灯光控制器与灯具设备进行数据传输的标准。它包括电气特性,数据协议,数据格式等方面的内容。
512协议规定使用的波特率是250kbps,但是stm32可以支持shangmbps的波特率,所以说这不是什么大问题。
该协议发送的数据帧一共11位,1位开始位,8位数据,2个停止位,无校验位。
根据波特率可以知道,位时间是4us,11位数据供需要44us的时间。当然对于标准的512协议是需要break和mark after break 帧的,break是一个92us的低电平,而mark after break是一个12us的高电平,如下图所示
根据上面的图片(缺失了起始码,下图补上),512协议必须有break和mark,但是在我们通常的非标准收发中,检测break和mark相对比较困难,如果非要做,耗费的资源也比较多,比如定时器计时,中断等等。如果不是做标准控制器的,完全可以另辟蹊径。
根据512 协议,每一串数据的开始都要有一个起始码,也称复位码,其数据为0,但是从开始位数至第十位是0,用来声明数据传输开始,随后包含1-512个数据,也称调光数据,其是标准的数据帧,所以第十位是1,所以我们可以根据这个第十位来进行做文章。大家都知道,一般的单片机,像51,avr等都是支持8-9位数据发送的,所以我们就是用9位数据,1位停止位,无校验位,通过检测检测第十位,也就是所谓的rb8来进行数据的接收与传输,不需要发送break和mark。
1、发送端
串口设为 9位数据,1停止位,无校验位,波特率250000
void usart1_configuration(void)
{
usart_inittypedef usart_initstructure;
usart_initstructure.usart_baudrate = 250000;
usart_initstructure.usart_wordlength = usart_wordlength_9b;
usart_initstructure.usart_stopbits = usart_stopbits_1;
usart_initstructure.usart_parity = usart_parity_no;
usart_initstructure.usart_hardwareflowcontrol = usart_hardwareflowcontrol_none;
usart_initstructure.usart_mode = usart_mode_rx | usart_mode_tx;
/* configure usart1 */
usart_init(usart1, &usart_initstructure);
/* enable usart1 receive and transmit interrupts */
usart_itconfig(usart1, usart_it_rxne, enable);
//usart_itconfig(usart1, usart_it_tc, enable);
/* enable the usart1 */
usart_cmd(usart1, enable);
}
注意在初始化串口的时候别忘了485芯片设为发送状态
接下来主要就是数据包的发送,发送的时候注意起始码的数据第九位设为0,调光数据第九位设为1.
void dmx_sendpacket(void)
{
pdmx_buf = 0;
while (pdmx_buf 《= 512) //1-512
{
/* send data packet to slaves*/
if(usart1-》sr & (1《《6))
{
/*发送起始码 00*/
if (0 == pdmx_buf)
{
usart1-》dr = ((usart1-》dr) & 0xfe00); //第九位置0
}
else
{
usart1-》dr = 0x0100 | dmx_buf[pdmx_buf]; //第九位置1
}
pdmx_buf++;
}
}
}
以上函数相比大家都可以看懂,接下来就是在main函数中进行循环数据的发送了,比如每200ms发送一次,由于发送快,偶尔的错误也不是很明显。
2,、接收端
接收端得工作就是接收的信息进行解码(废话),关键是对rb8的处理,接收用到了中断接收,所以需要使能接收中断。
void usart1_configuration(void)
{
usart_inittypedef usart_initstructure;
usart_initstructure.usart_baudrate = 250000;
usart_initstructure.usart_wordlength = usart_wordlength_9b;
usart_initstructure.usart_stopbits = usart_stopbits_1;
usart_initstructure.usart_parity = usart_parity_no;
usart_initstructure.usart_hardwareflowcontrol = usart_hardwareflowcontrol_none;
usart_initstructure.usart_mode = usart_mode_rx | usart_mode_tx;
/* configure usart1 */
usart_init(usart1, &usart_initstructure);
/* enable usart1 receive and transmit interrupts */
usart_itconfig(usart1, usart_it_rxne, enable);//使能接收中断
//usart_itconfig(usart1, usart_it_tc, enable);
/* enable the usart1 */
usart_cmd(usart1, enable);
}
void nvic_configuration(void)
{
nvic_inittypedef nvic_initstructure;
#ifdef vect_tab_ram
/* set the vector table base location at 0x20000000 */
nvic_setvectortable(nvic_vecttab_ram, 0x0);
#else /* vect_tab_flash */
/* set the vector table base location at 0x08000000 */
nvic_setvectortable(nvic_vecttab_flash, 0x0);
#endif
//设置优先级分组:先占优先级和从优先级 ,先占优先级0位,从优先级4位
nvic_prioritygroupconfig(nvic_prioritygroup_0);
/* enable the usart1 interrupt */
nvic_initstructure.nvic_irqchannel = usart1_irqn;
nvic_initstructure.nvic_irqchannelpreemptionpriority = 0;
nvic_initstructure.nvic_irqchannelsubpriority = 1;
nvic_initstructure.nvic_irqchannelcmd = enable;
nvic_init(&nvic_initstructure);
}
void usart1_irqhandler(void)
{
uint16_t udr;
static uint16_t rxb8;
static uint16_t pdmx_buf = 0; //数据指针
static uint8_t fdmx_buf_right = 0;
//接收数据
if(usart_getitstatus(usart1, usart_it_rxne) != reset)//usart_flag_rxne
{
//usart_clearitpendingbit(usart1,usart_flag_rxne);
udr = usart_receivedata(usart1);
rxb8 = (udr & 0x0100);
if (rxb8 == 0) //复位信号
{
if (!udr)
{
fdmx_buf_right = 1;//接收数据正确
pdmx_buf = 1; //直接接收第一个数据 不保存第0个数据。
}
}
else //rb8 =1 pdmx_buf=1 调光数据
{
if (1 == fdmx_buf_right)
{
dmx_buf[pdmx_buf++] = (u8)udr;
//接收到512个数据
if (pdmx_buf 》 512)
{
fdmx_buf_right = 0;
tim_update = set; //更新调光数据
}
}
}
}
}
变速箱对于电动汽车而言到底有没有用
对数字电源管理的需求
如何全面提高地方立法质量?人工智能可以助一臂之力
【知识】负荷开关与隔离开关、真空断路器的区别
阀门锁的选择以及日常护理常识的介绍
基于stm32实现DMX512协议发送与接收详解
奥士康:泰国基地一期已封顶,预计明年Q2试产
在变革与自救中 彩电市场必将迎来新一轮的清洗
车载无线充电技术与标准化研究
OSVR将获得Steam平台的支持 扩展大量VR内容的来源
直线马达产品亮相2021轨博会
用于高端嵌入式/中级服务器的COM-HPC标准
华为Mate60 Pro搭载麒麟9000S
三星电子2023年销售额与营业利润大幅下滑,半导体业务受挫
ISO122构成的增益可编程隔离放大器
什么是激光?激光器产生激光的原理
几种不间断电源并机办法,长期空载运行
爱立信40%消费者用于5G网络下的增强视频
如何来实现一台主机带动六台显示器
幼儿点读笔有没有用?点读笔对小孩的用处