STM32F103VG使用RTT实现发送DMX512调光数据

DMX512调光协议和DALI一样属于数字调光协议,一个完整的DMX512数据包格式:1break+1mab+1startcode+512个调光数据。

DMX512发送是基于485串口的基础上实现的特殊的数据协议。

使用RTT需要把串口打开并且定义好相应的定义,这里不再赘述;因RTT的部分外设初始化不完善,本次使用的HAL库进行初始化部分。

实现步骤:

1.初始化GPIO口,使能485串口的3.3v以及使能为发送模式,这个根据实际需求进行初始化

/*
 * 初始化dmx512所要用到的pin,打开485的3.3v以及使能发送模式   PC8 3.3v, PC9 模式控制
 * */
int dmx512_pin_init(void)
{
    GPIO_InitTypeDef GPIO_InitStruct = {0};
    __HAL_RCC_GPIOC_CLK_ENABLE();

     /*Configure GPIO pin Output Level */
     HAL_GPIO_WritePin(GPIOC, GPIO_PIN_9, GPIO_PIN_SET);

     /*Configure GPIO pin Output Level */
     HAL_GPIO_WritePin(GPIOC, GPIO_PIN_8, GPIO_PIN_RESET);

     /*Configure GPIO pins : PC7 PC8 PC9 */
     GPIO_InitStruct.Pin = GPIO_PIN_8|GPIO_PIN_9;
     GPIO_InitStruct.Mode = GPIO_MODE_OUTPUT_PP;
     GPIO_InitStruct.Pull = GPIO_NOPULL;
     GPIO_InitStruct.Speed = GPIO_SPEED_FREQ_LOW;
     HAL_GPIO_Init(GPIOC, &GPIO_InitStruct);

     return RT_EOK;
}

2.初始化要用到的485串口,数据位9,波特率250000

/*
 * 初始化dmx512所要用到的uart4
 * */
int dmx512_uart_init(void)
{
    GPIO_InitTypeDef GPIO_InitStruct = {0};
    __HAL_RCC_UART4_CLK_ENABLE();
    __HAL_RCC_GPIOC_CLK_ENABLE();

    GPIO_InitStruct.Pin = GPIO_PIN_10;
    GPIO_InitStruct.Mode = GPIO_MODE_AF_PP;
    GPIO_InitStruct.Speed = GPIO_SPEED_FREQ_HIGH;
    HAL_GPIO_Init(GPIOC, &GPIO_InitStruct);

    GPIO_InitStruct.Pin = GPIO_PIN_11;
    GPIO_InitStruct.Mode = GPIO_MODE_INPUT;
    GPIO_InitStruct.Pull = GPIO_NOPULL;
    HAL_GPIO_Init(GPIOC, &GPIO_InitStruct);

    huart4.Instance = UART4;
    huart4.Init.BaudRate = 250000;
    huart4.Init.WordLength = UART_WORDLENGTH_9B;
    huart4.Init.StopBits = UART_STOPBITS_1;
    huart4.Init.Parity = UART_PARITY_NONE;
    huart4.Init.Mode = UART_MODE_TX_RX;
    huart4.Init.HwFlowCtl = UART_HWCONTROL_NONE;
    huart4.Init.OverSampling = UART_OVERSAMPLING_16;
    HAL_UART_Init(&huart4);

    return RT_EOK;
}

3.写一个切换串口引脚功能的函数,用于形成break和mab信号

/*
 * 切换dmx512发送pin脚的模式
 * */
int dmx512_pin_mode(int mode)
{
    GPIO_InitTypeDef GPIO_InitStructure;

    if(mode)    //mode=1,当串口发送用,在dmx512发送中主要用于发送数据帧
    {
        GPIO_InitStructure.Pin = GPIO_PIN_10;
        GPIO_InitStructure.Mode = GPIO_MODE_AF_PP; //复用推挽输出
        GPIO_InitStructure.Speed = GPIO_SPEED_FREQ_HIGH;
        HAL_GPIO_Init(GPIOC, &GPIO_InitStructure);
    }
    else if(mode == 0)//mode=0,当普通io用,在dmx512发送中主要用来形成break和mab信号
    {
        GPIO_InitStructure.Pin = GPIO_PIN_10;
        GPIO_InitStructure.Mode = GPIO_MODE_OUTPUT_PP;  //推挽输出
        GPIO_InitStructure.Speed = GPIO_SPEED_FREQ_HIGH;
        HAL_GPIO_Init(GPIOC, &GPIO_InitStructure);
    }
    return RT_EOK;
}

4.写DMX512的数据发送函数,定义全局变量 int pDMX_buf、char dmx_buf[513]

/*
 * dmx512发送数据函数
 * */
int dmx512_send_frame(void)
{
    dmx512_pin_mode(0);
    HAL_GPIO_WritePin(GPIOC, GPIO_PIN_10, 0);
    rt_hw_us_delay(100);
    HAL_GPIO_WritePin(GPIOC, GPIO_PIN_10, 1);
    rt_hw_us_delay(10);
    dmx512_pin_mode(1);

    for(pDMX_buf = 0; pDMX_buf <= 512; pDMX_buf++)  //0:startcode   1-512:调光数据
    {

        if(pDMX_buf == 0)
        {
            UART4->DR = 0x00 | 0x100;//第一帧startcode
            while((UART4->SR & 0X40) == 0); //确保数据发送完成
        }

        else
        {
            UART4->DR = 0x100 | dmx_buf[pDMX_buf];
            while((UART4->SR & 0X40) == 0);     //确保数据发送完成
        }

    }
    return RT_EOK;
}

5.写一个DMX512的初始化函数,可以把前面的初始化的所有函数放进去并开启线程用于发送DMX512数据

*
 * 包含了dmx512所用到的所有初始化,并开启线程发送dmx512数据
 * */
int dmx512_init(void)
{
    int ret = RT_EOK;
    dmx512_pin_init();
    dmx512_uart_init();
    /* 创建 serial 线程 */
    rt_thread_t thread = rt_thread_create("dmx512", dmx512_send_thread, RT_NULL, 1024, 25, 10);
    /* 创建成功则启动线程 */
    if (thread != RT_NULL)
    {
        rt_thread_startup(thread);
    }
    else
    {
        ret = RT_ERROR;
    }

    return ret;
}

6.实现线程函数,每隔400ms发送一个DMX512数据包

/*
 * dmx512数据发送线程,dmx512数据需要持续发送而且必须在1S内发送下一条
 * */
static void dmx512_send_thread(void *parameter)
{
    while(1)
    {
        dmx512_send_frame();
        rt_thread_mdelay(400);
    }

}

7.将dmx512_init放到MAIN中执行即可。

版权声明:本文为CSDN博主「小火汁-,-」的原创文章,遵循CC 4.0 BY-SA版权协议,转载请附上原文出处链接及本声明。
原文链接:https://blog.csdn.net/weixin_43962818/article/details/122842364

生成海报
点赞 0

小火汁-,-

我还没有学会写个人说明!

暂无评论

发表评论

相关推荐

stm32小车红外对管的循迹

为了参加校内赛写了分技术报告和相关代码 但是不想就这么浪费了 https://www.yuque.com/docs/share/a64051d0-cc1e-4e45-a704-db7a9af5cb76?# 《电控技术报告》 电控技术报告