STM8S003F3P6采用内部16M晶振。我看市场上面有使用这个单片机采用内部晶振进行控制的。不知道为什么我总是控制不到。
一个NOP是68NS 左右 空指令符合规格书要求Send_Dat = 1; 但是空指令后Send_Dat = 0;时间就变为1.2US了
同样的单片机 我不知道别人怎么做到Send_Dat = 1的时候850NS的。有没有高手指导指导一下。(我i采集过市场上面的他可以做到850NS)
- /* 添加包含芯片的头文件 */
- #include<iostm8s103f3.h>
- #define nop() asm("nop");
- #define LED PB_ODR_ODR5
- #define Send_Dat PC_ODR_ODR7 //数据输出,接pb5脚
- #define Number 100
- typedef unsigned char uint8;
- typedef unsigned int uint16;
- //定义全局变量
- /*******************************************************************************
- **函数名称:void Send_8bit(uchar dat)
- **功能描述:发送24个字节
- **入口参数:无
- **输出:无
- *******************************************************************************/
- void send_24bits(uint8 dat1,uint8 dat2,uint8 dat3) //WS2811B
- {
- uint8 a;
- for(a=0;a<8;a++)
- {
- if(dat1&0x80) //code"1"
- {
- Send_Dat = 1;
- nop();
- nop();
- nop();
- nop();
- nop();
- Send_Dat = 0;
- }
- else
- {
- Send_Dat = 1; //code"0"
- nop();
- nop();
- nop();
- nop();
- nop();
- nop();
- nop();
- nop();
- nop();
- nop();
- nop();
- nop();
- nop();
- nop();
- Send_Dat = 0;
- }
- dat1 = dat1<<1;
- }
- for(a=0;a<8;a++)
- {
- if(dat2&0x80) //code"1"
- {
- Send_Dat = 0;
- nop();
- nop();
- nop();
- nop();
- nop();
- Send_Dat = 1;
- }
- else
- {
- Send_Dat = 1; //code"0"
- nop();
- nop();
- nop();
- nop();
- nop();
- nop();
- nop();
- nop();
- nop();
- nop();
- nop();
- nop();
- nop();
- nop();
- Send_Dat = 0;
- }
- dat1 = dat2<<1;
- }
- for(a=0;a<8;a++)
- {
- if(dat3&0x80) //code"1"
- {
- Send_Dat = 0;
- nop();
- nop();
- nop();
- nop();
- nop();
- Send_Dat = 1;
- }
- else
- {
- Send_Dat = 1; //code"0"
- nop();
- nop();
- nop();
- nop();
- nop();
- nop();
- nop();
- nop();
- nop();
- nop();
- nop();
- nop();
- nop();
- nop();
- Send_Dat = 0;
- }
- dat1 = dat3<<1;
- }
- }
- /*******************************************************************************
- **函数名称:void Delay_us(uint16 x)
- **功能描述:延时函数
- **入口参数:无
- **输出:无
- *******************************************************************************/
- void Delay_us(uint16 x)
- {
- uint8 j,k;
- for(j=x;j>0;j--)
- for(k=120;k>0;k--);
- }
- /*******************************************************************************
- **函数名称:rest()
- **功能描述:复位函数
- **入口参数:无
- **输出:无
- *******************************************************************************/
- void rest() //复位
- {
- Send_Dat = 0;
- Delay_us(1);
- }
- /*******************************************************************************
- **函数名称:void Timer2Init()
- **功能描述:定时器2参数初始化
- **入口参数:无
- **输出:无
- *******************************************************************************/
- void Timer2Init()
- {
- TIM2_PSCR = 0x00; //定时器2预分频数为 1 分频,即定时器时钟 = 系统时钟 = 16MHz
- TIM2_ARRH = 0x3e; //设置1毫秒时间自动重载 16000 = 0x3e80
- TIM2_ARRL = 0x80; //
- TIM2_CNTRH = 0; //清除计数寄存器
- TIM2_CNTRL = 0; //
- TIM2_IER = 0x01; //使能定时器2允许更新中断
- TIM2_SR1 = 0x00; //清除所有的中断标示
- TIM2_CR1 = 0x81; //使能计数器,并允许自动预装
- }
- /*******************************************************************************
- **函数名称:void LED2Init()
- **功能描述:LED2->功能引脚初始化
- **入口参数:无
- **输出:无
- *******************************************************************************/
- void Init_GPIO()
- {
- PB_DDR_DDR5 = 1;
- PB_CR1 = 0xff;
- PB_CR2 = 0x00;
- PC_DDR_DDR7 = 1;
- PC_CR1 = 0xff;
- PC_CR2 = 0x00;
- }
- void rest_all()
- {
- uint16 i;
- for(i=0;i<Number;i++)
- {
- send_24bits(0,0,0);
- }
- rest();
- }
- void Five_Color_Flow() //5个同色灯珠流水
- {
- uint8 i=0,mode_flag=0;
- char a,b=0;
- rest_all();
- while(1)
- {
- for(i=0;i<Number;i++)
- {
- if(a<5) send_24bits(255,0,0);
- else if(a<10) send_24bits(0,255,0);
- else if(a<15) send_24bits(0,0,255);
- else if(a<20) send_24bits(255,255,0);
- else if(a<25) send_24bits(0,255,255);
- else if(a<30) send_24bits(255,255,0);
- else send_24bits(255,255,255);
- a++;
- if(a>34) a=0;
- }
- rest();
- Delay_us(150);
- b--;
- if(b<0) b=34;
- }
- }
- /*******************************************************************************
- **函数名称:主函数
- **功能描述:1=55US
- **入口参数:无
- **输出:无
- *******************************************************************************/
- int main(void)
- {
- asm("sim"); //先关闭总中断
- CLK_CKDIVR = 0x00; //CPUDIV = 1 HSIDIV = 1 内部时钟 = 16Mhz
- Init_GPIO(); //初始化IO口
- Timer2Init(); //调用定时器2初始化函数
- asm("rim"); //打开总中断
- while(1) //进入死循环,等待定时器2周期中断
- {
- send_24bits(255,0,0) ;
- }
- }
- /*******************************************************************************
- **函数名称:__interrupt void TIM2_UPDATE_IRQHandler(void)
- **功能描述:定时器2重载更新中断服务函数
- **入口参数:无
- **输出:无
- *******************************************************************************/
- #pragma vector = 15 //设置定时器2重载的中断向量号 = 15
- __interrupt void TIM2_UPDATE_IRQHandler(void)
- {
- TIM2_SR1 = 0x00; //清除中断标志
- /* ms_count++; //中断使 ms_count++ 做加法,记录1毫秒产生的中断次数
- if(ms_count >= 1000) //记录达到1000毫秒,即1秒
- {
- ms_count = 0; //复位记录中断次数
- // PC_ODR ^= 0x80; //对LED2进行异或取反,使LED2以1秒的周期亮灭
- }
- */
- }
复制代码 |