|
怎样做个蜘蛛精(六) 大家别找了,(一)、(二)(三)(四)(五)都没有发表,本来这个(六)也没有想着发表(懒癌犯了),但是文中的一个函数的应用,不得不让我把它提前单独发表。
美滋滋的想着挂上就能用了,先是把厂家送的资料都看了看,把语音模块放入写码器,按规格写入一段语音,选用按键模式,给写码器配个耳机,语音模块在按键模式下正常,但是看看厂家给的三线模式的程序都是PIC,51的,没有STM32的,这个也难不倒我,上网查查看,找到了几个STM32的程序都是在正点原子程序中使用的,我用STM32F103RC测试一下,发现只有一个程序能用,唯一麻烦的是我的蜘蛛精主控是STM32F401CC,而且是用STM32CUBEMX,HAL库的,这个还要把程序改了才能用,这个又要改芯片,又要改程序,于是又把程序按照HAL库的写法,重新写过,Delay_us(150)的延时程序没有写,当时我就想,HAL库设计时没有考虑US级的延时,只考虑MS级的延时吗?不管这个函数的说明是怎样的,我试下HAL_Delay(0.15)能否代替Delay_us(150),如果不行,恐怕连编译都不能通过,然而,奇迹就此发生了,它通过了编译,并且成功使得我的蜘蛛精发出它的第一声叫喊“别碰我,你个臭唐僧,难道不知道我是蜘蛛精吗”。! X# `5 m; s5 c2 A- x" b4 W6 H3 l' o
/*************51**************/4 [+ l i1 S" C4 l$ u //三线; M/ X# @' e5 D7 j; s) X0 t sbit P_DATA_3A = P0^0; //定义数据传输% q" l0 T; G+ V) d8 I( G1 O- U! E sbit CS_3A = P0^1; //定义片选, w! l0 m3 f! b: F5 X1 j sbit CLK_3A = P0^2; //定义时钟 bit B_DATA; //´«ÊäÊý¾Ýһλ& e, b4 ~8 {( k& K6 h) Z unsigned char SB_DATA = 0; //传输数据一位5 Z Q4 n/ _( t+ Z( {! k unsigned char S_DATA = 0x00;( Z& A2 \2 E3 y5 f' I + Q& p% Z! F4 Y) {# w) k9 M# }! f( ] /*-------------------------------------- ;三线单字节低位在前串口通信函数 void Line_3A(unsigned char dat); _/ B/ a0 p% U: x4 q4 Q& M { unsigned char i,key_copy = 0X00; P_DATA = 1; CLK_3A = H; //拉高 . Z+ q$ Y0 U0 }0 ^ CS_3A= L; //拉低片选 Delay_1ms(5); //5ms6 U4 P4 w: B& W B_DATA = dat&0X01; for(i=0;i<8;i++)2 X% w* w' u6 P+ a/ f {: x& U& ?# c2 u CLK_3A = L; //拉低" C) _; i1 @6 @5 R$ w6 p1 V- U P_DATA_3A = B_DATA; //传输数据一位 , r- E: O+ x! Y1 _6 n8 H9 Q Delay_10us(15); //延时150us CLK_3A = H; //拉高3 Z2 G2 Q8 `& X9 R2 Q- H Delay_10us(15); //延时150us2 D! N }, e! j/ @: p8 e7 Y) M dat = dat>>1; B_DATA = dat&0X01; 5 z# J7 G/ r O2 f } P_DATA_3A = 1; //拉高电平 CS_3A = H; ( V1 k3 ?" a. {# [( U CLK_3A = H; }; S! C+ F9 K8 l5 ?- r& [ /****************51程序结束********************/ /***********标准库正点原子*****************/ //发送数据函数 // PA14(SCL) 时钟4 y- A( X* _8 V3 a M" G+ Y( @ // PA12(CS) 片选 // PA13(DATA) 数据 //PBout(0) 复位信号 void YUY_Chul(uint16_t addr) {2 V5 q$ q8 H! d0 w; j% c3 K9 p unsigned char i;# l8 H/ N, f1 _ delay_ms(20); GPIO_ResetBits(GPIOB,GPIO_Pin_12); // CS=0; $ D' _2 n3 O0 n2 c! C) r delay_ms(5);& V( l% B; L, l1 m- q* x$ r for(i=0;i<8;i++) / a. V3 N8 W# k3 S4 ] {6 _5 g' w/ W _2 ^# C, n* t0 B GPIO_ResetBits(GPIOB,GPIO_Pin_14); //SCL=0; if(addr & 1)GPIO_SetBits(GPIOB,GPIO_Pin_13); //DATA=1; $ I/ l% \1 F" M' x2 I7 t; e% l* q else GPIO_ResetBits(GPIOB,GPIO_Pin_13); //DATA=0; # V8 h9 o4 D* w$ T addr>>=1; ) Y. u0 o! z* r delay_us(150); /* 150us */ % o3 Z5 B# N# t5 a GPIO_SetBits(GPIOB,GPIO_Pin_14); //SCL=1; / U9 }( T4 [: I2 q# w% r delay_us(150); } GPIO_SetBits(GPIOB,GPIO_Pin_12); //CS=1;- i. @6 _1 }9 g$ f } /***********标准库正点原子程序结束*************/# e7 j B' }0 l7 I( ^" A9 s /***********HAL*****************/* Z. E! e" M6 G( d* C //发送数据函数5 p" o& v' O6 ~! ]% b9 ] // PA14(SCL) 时钟 // PA12(CS) 片选 // PA13(DATA) 数据2 ^' m! e; Y2 F, j8 _1 c+ @ A //PBout(0) 复位信号# Q% k# }! ~- Q) X w9 u L void YUY_Chul(uint16_t addr) {% V7 e2 \3 [9 y% _9 ?2 N unsigned char i; HAL_Delay(20);0 l: q' U; ~7 }* C) e1 W HAL_GPIO_WritePin(GPIOB, GPIO_PIN_12, GPIO_PIN_RESET);// CS=0; HAL_Delay(5);8 c& Y, b u" E9 B- V for(i=0;i<8;i++) 5 f g- _( i% D5 H' C { HAL_GPIO_WritePin(GPIOB, GPIO_PIN_14, GPIO_PIN_RESET); //SCL=0; ( \4 O; W3 |3 @3 `8 n7 f if(addr & 1)8 _ @( ^' I+ c, f HAL_GPIO_WritePin(GPIOB, GPIO_PIN_13, GPIO_PIN_SET);//DATA=1; else HAL_GPIO_WritePin(GPIOB, GPIO_PIN_13, GPIO_PIN_RESET);//DATA=0; addr>>=1; HAL_Delay(0.15);/* 150us */" M; ]) G6 G1 N/ j HAL_GPIO_WritePin(GPIOB, GPIO_PIN_14, GPIO_PIN_SET);//SCL=1; HAL_Delay(0.15);/* 150us */ } : h w* C6 k7 ?! C5 L HAL_GPIO_WritePin(GPIOB, GPIO_PIN_12, GPIO_PIN_SET);//CS=1; }# Z: R& {1 T$ R3 g9 i /***********HAL程序结束*****************/ 在此就HAL_Delay()函数和大家聊一聊,我一直没有发现有这样用的,而且发现正点原子的HAL库的程序也不用HAL_Delay()函数,好像是因为中断优先级缘故,导致程序跑飞。难道这个函数的设计这么不堪?毕竟是老外的设计,老外的思想咱一时还摸不透,有同学认为按着HAL_Delay()函数的定义,HAL_Delay(0.15)会等同于HAL_Delay(0),然而实事却不是这样,你们也许有更高明的解释,但是我只是突发奇想,并用实事告诉你,不是你理解有误,就是这个函数解释有问题。实事上我也没有最终搞明白这个HAL_Delay(0.15)这么用为啥能行。我还等着你的解释那。$ l6 e' y5 y) M# _2 o2 i; b+ r |
微信公众号
手机版
你能解释下为啥HAL_Delay(0.15);能用?
你确定能用?0.15有警告,实际会转化为0,等效HAL_Delay(0),里面有几行代码,估计也就是几个微秒就执行完毕。
你说0.15是150us,用示波器测试了吗?% {- _, b2 y W' G" Z
示波器测试还没有,但是根据WT588D的手册,这个延时时间必须控制在300US以内,否则就不起作用了。有个玩具示波器可以测试下。KILE里HAL_Delaly(0.15);不会报错,能通过编译。