久久久久久久999_99精品久久精品一区二区爱城_成人欧美一区二区三区在线播放_国产精品日本一区二区不卡视频_国产午夜视频_欧美精品在线观看免费

標(biāo)題: STM32F103C8T6單片機(jī)驅(qū)動(dòng)WS2812,從零到放棄 [打印本頁(yè)]

作者: n04769431433    時(shí)間: 2024-10-27 23:25
標(biāo)題: STM32F103C8T6單片機(jī)驅(qū)動(dòng)WS2812,從零到放棄
首先是WS2812引腳初始化代碼,這點(diǎn)和其他配置GPIO代碼相同
void WS2812_PinInit(void)
{
        RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOB,ENABLE);
        GPIO_InitTypeDef GPIO_InitStructure;
        GPIO_InitStructure.GPIO_Pin = GPIO_Pin_11;
        GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
        GPIO_InitStructure.GPIO_Mode = GPIO_Mode_Out_PP;
        GPIO_Init(GPIOB,&GPIO_InitStructure);
        WS2812_Reset();
}

其次是要向WS2812發(fā)送數(shù)據(jù),我們看一下WS2812時(shí)序要求


可以看到WS2812對(duì)時(shí)間要求比較嚴(yán)格,我們來(lái)操作GPIO
首先如果直接調(diào)用庫(kù)函數(shù)中的GPIO_SetBits()GPIO_ResetBits()函數(shù)
我們來(lái)試一下
int main(void)
{
        WS2812_PinInit();
        while(1)
        {
                GPIO_SetBits(GPIOB,GPIO_Pin_11);
                GPIO_ResetBits(GPIOB,GPIO_Pin_11);
        }
}



可以看到,單片機(jī)主頻72MHz才堪堪達(dá)到要求,如果更換其他型號(hào)主頻較低的單片機(jī),可能就達(dá)不到要求了
我們打開(kāi)GPIO_SetBits()GPIO_ResetBits()函數(shù)
void GPIO_SetBits(GPIO_TypeDef* GPIOx, uint16_t GPIO_Pin)
{
  assert_param(IS_GPIO_ALL_PERIPH(GPIOx));
  assert_param(IS_GPIO_PIN(GPIO_Pin));
  GPIOx->BSRR = GPIO_Pin;
}
void GPIO_ResetBits(GPIO_TypeDef* GPIOx, uint16_t GPIO_Pin)
{
  assert_param(IS_GPIO_ALL_PERIPH(GPIOx));
  assert_param(IS_GPIO_PIN(GPIO_Pin));
  GPIOx->BRR = GPIO_Pin;
}


其中,assert_param()函數(shù)在這里的作用是檢查GPIO_SetBits庫(kù)函數(shù)傳入的參數(shù)是否為真,如果為真,就什么也不執(zhí)行,如果為假,就會(huì)在源程序編譯的時(shí)候報(bào)錯(cuò)!
GPIOx->BSRR = GPIO_Pin;就是操作GPIO引腳設(shè)置高電平
   GPIOx->BRR = GPIO_Pin;  就是操作GPIO引腳設(shè)置低電平
那么,具體怎么操作呢
int main(void)
{
        WS2812_PinInit();
        while(1)
        {
                GPIOB->BSRR = GPIO_Pin_11;  //拉高PB11
                GPIOB->BRR   = GPIO_Pin_11;  //拉低PB11
        }
}



可以看到,高電平時(shí)間由原來(lái)的約160us變?yōu)榱爽F(xiàn)在的約40us
接下來(lái)就開(kāi)始向WS2812發(fā)送 ‘0’ 碼
int main(void)
{
        WS2812_PinInit();
        while(1)
        {
                GPIOB->BSRR = GPIO_Pin_11;//拉高PB11
                __NOP();__NOP();__NOP();__NOP();__NOP();__NOP();
                __NOP();__NOP();__NOP();__NOP();__NOP();__NOP();
                GPIOB->BRR  = GPIO_Pin_11;//拉低PB11
        }
}



可以看到,在添加12個(gè)nop函數(shù)后,高電平時(shí)序大概能滿足要求了
接下來(lái)就是滿足低電平的時(shí)間
int main(void)
{
        WS2812_PinInit();
        while(1)
        {
                GPIOB->BSRR = GPIO_Pin_11;//拉高PB11
                __NOP();__NOP();__NOP();__NOP();__NOP();__NOP();
                __NOP();__NOP();__NOP();__NOP();__NOP();__NOP();
                GPIOB->BRR  = GPIO_Pin_11;//拉低PB11
                __NOP();__NOP();__NOP();__NOP();__NOP();__NOP();
                __NOP();__NOP();__NOP();__NOP();__NOP();__NOP();
                __NOP();__NOP();__NOP();__NOP();__NOP();__NOP();
                __NOP();__NOP();__NOP();__NOP();__NOP();__NOP();
                __NOP();__NOP();__NOP();__NOP();__NOP();__NOP();
        }
}



低電平延時(shí)大概30個(gè)nop
接下來(lái)就是 ‘1’ 碼
int main(void)
{
        WS2812_PinInit();
        while(1)
        {
                GPIOB->BSRR = GPIO_Pin_11;//拉高PB11
                __NOP();__NOP();__NOP();__NOP();__NOP();__NOP();
                __NOP();__NOP();__NOP();__NOP();__NOP();__NOP();
                __NOP();__NOP();__NOP();__NOP();__NOP();__NOP();
                __NOP();__NOP();__NOP();__NOP();__NOP();__NOP();
                __NOP();__NOP();__NOP();__NOP();__NOP();__NOP();
                __NOP();__NOP();__NOP();__NOP();__NOP();__NOP();
                GPIOB->BRR  = GPIO_Pin_11;//拉低PB11
                __NOP();__NOP();__NOP();__NOP();__NOP();__NOP();
        }
}



因?yàn)橐喜蓚(gè)函數(shù),所以預(yù)留了一點(diǎn)時(shí)間
接下來(lái)合并函數(shù)
void WS2812_SendBit(uint8_t Bit);
int main(void)
{
        WS2812_PinInit();
        while(1)
        {
                WS2812_SendBit(1);
                WS2812_SendBit(0);
        }
}
void WS2812_SendBit(uint8_t Bit)
{
        GPIOB->BSRR = GPIO_Pin_11;//拉高PB11
        __NOP();__NOP();__NOP();__NOP();__NOP();__NOP();
        __NOP();__NOP();__NOP();__NOP();__NOP();__NOP();
        if(Bit != 0)
                GPIOB->BRR = GPIO_Pin_11;//拉低PB11
        __NOP();__NOP();__NOP();__NOP();__NOP();__NOP();
        __NOP();__NOP();__NOP();__NOP();__NOP();__NOP();
        __NOP();__NOP();__NOP();__NOP();__NOP();__NOP();
        __NOP();__NOP();__NOP();__NOP();__NOP();__NOP();
        GPIOB->BRR = GPIO_Pin_11;//拉低PB11
        __NOP();__NOP();__NOP();__NOP();__NOP();__NOP();
}


可以看到,波形是可以滿足時(shí)序要求的
接下來(lái)就是向WS2812發(fā)送 3 字節(jié)的RGB數(shù)據(jù)
需要注意的是,WS2812數(shù)據(jù)發(fā)送順序是G R B,也就是綠色在前,然后是紅色,藍(lán)色。而不是紅色,綠色,藍(lán)色
void WS2812_SendRGB(uint8_t R,uint8_t G,uint8_t B);
int main(void)
{
        WS2812_PinInit();
        WS2812_SendRGB(50,0,0);
        while(1)
        {
        }
}

void WS2812_SendRGB(uint8_t R,uint8_t G,uint8_t B)
{
        for(int i = 0;i < 8;i ++)                                                                        //發(fā)送8位綠色數(shù)據(jù)
        {
                GPIOB->BSRR = GPIO_Pin_11;//拉高PB11
                __NOP();__NOP();__NOP();__NOP();__NOP();__NOP();
                __NOP();__NOP();__NOP();__NOP();__NOP();__NOP();
                if((G & (0x80 >> i)) == 0)
                        GPIOB->BRR  = GPIO_Pin_11;//拉低PB11
                __NOP();__NOP();__NOP();__NOP();__NOP();__NOP();
                __NOP();__NOP();__NOP();__NOP();__NOP();__NOP();
                __NOP();__NOP();__NOP();__NOP();__NOP();__NOP();
                __NOP();__NOP();__NOP();__NOP();__NOP();__NOP();
                GPIOB->BRR  = GPIO_Pin_11;//拉低PB11
                __NOP();__NOP();__NOP();__NOP();__NOP();__NOP();
        }
        for(int i = 0;i < 8;i ++)                                                                        //發(fā)送8位紅色數(shù)據(jù)
        {
                GPIOB->BSRR = GPIO_Pin_11;//拉高PB11
                __NOP();__NOP();__NOP();__NOP();__NOP();__NOP();
                __NOP();__NOP();__NOP();__NOP();__NOP();__NOP();
                if((R & (0x80 >> i)) == 0)
                        GPIOB->BRR  = GPIO_Pin_11;//拉低PB11
                __NOP();__NOP();__NOP();__NOP();__NOP();__NOP();
                __NOP();__NOP();__NOP();__NOP();__NOP();__NOP();
                __NOP();__NOP();__NOP();__NOP();__NOP();__NOP();
                __NOP();__NOP();__NOP();__NOP();__NOP();__NOP();
                GPIOB->BRR  = GPIO_Pin_11;//拉低PB11
                __NOP();__NOP();__NOP();__NOP();__NOP();__NOP();
        }
        for(int i = 0;i < 8;i ++)                                                                        //發(fā)送8位藍(lán)色數(shù)據(jù)
        {
                GPIOB->BSRR = GPIO_Pin_11;//拉高PB11
                __NOP();__NOP();__NOP();__NOP();__NOP();__NOP();
                __NOP();__NOP();__NOP();__NOP();__NOP();__NOP();
                if((B & (0x80 >> i)) == 0)
                        GPIOB->BRR  = GPIO_Pin_11;//拉低PB11
                __NOP();__NOP();__NOP();__NOP();__NOP();__NOP();
                __NOP();__NOP();__NOP();__NOP();__NOP();__NOP();
                __NOP();__NOP();__NOP();__NOP();__NOP();__NOP();
                __NOP();__NOP();__NOP();__NOP();__NOP();__NOP();
                GPIOB->BRR  = GPIO_Pin_11;//拉低PB11
                __NOP();__NOP();__NOP();__NOP();__NOP();__NOP();
        }
}


可以看到,這顆燈珠已經(jīng)可以被點(diǎn)亮了







作者: devcang    時(shí)間: 2024-10-28 09:37
arduino卻容易很多
作者: n04769431433    時(shí)間: 2024-10-28 10:05
最后一段代碼WS2812_SendRGB以前要放10ms上電延時(shí)!!!要放10ms上電延時(shí)!!!10ms上電延時(shí)!!!




歡迎光臨 (http://www.zg4o1577.cn/bbs/) Powered by Discuz! X3.1
主站蜘蛛池模板: 欧美精品在线观看 | 日韩精品欧美精品 | 久久国产精品视频 | 国产精品一区久久久 | 亚洲国产免费 | 免费黄色a视频 | 国产农村一级片 | 国产一级在线 | 亚洲午夜精品一区二区三区 | 视频在线观看亚洲 | 四色成人av永久网址 | 欧美视频中文字幕 | 成人免费在线观看视频 | 超碰97人人人人人蜜桃 | 欧美视频1| 黄色大片免费网站 | 国产在线精品一区二区三区 | 超碰男人天堂 | 亚洲欧美视频 | 九色网址 | 天天干天天草 | 日韩欧美中文字幕在线视频 | 中文字幕成人av | 成人欧美一区二区三区 | 人人做人人澡人人爽欧美 | 国产一区欧美一区 | 新超碰97| 精品一区二区久久久久久久网站 | 色综合天天天天做夜夜夜夜做 | 国产成人网 | 国产福利视频 | 中文字幕二区三区 | 久久精品免费一区二区 | 亚洲精品电影网在线观看 | 久久精品国产一区 | 亚洲国产网站 | 久久精品二区亚洲w码 | 久国产精品 | 81精品国产乱码久久久久久 | 久久国产视频网站 | 国产精品国产精品国产专区不片 |