你的浏览器版本过低,可能导致网站不能正常访问!
为了你能正常使用网站功能,请使用这些浏览器。

【经验分享】一文弄清51、STM32、Linux点灯的区别

[复制链接]
STMCU小助手 发布时间:2022-3-17 18:04
嵌入式初学者入门的第一个“项目”就是LED点灯,那么,本文带你看看51、STM32、Linux点灯有什么区别?
% N7 P# v8 v) _2 J* U1 H
51点灯
51点灯,是很多单片机初学者的首选,难度也是相对比较低的。
, r7 h2 L- Z! G; o9 t% Y; U, n3 s
准备工作:
  • 51开发板(以STC51单片机为例)
  • Keil C51、STC-ISP下载软件7 h1 ~0 f$ F2 ?8 d5 D
    7 c/ m2 u2 A+ y- \' B/ ]' }
' n. O2 S# N9 s0 m% u
51单片机开发,通常是直接操作寄存器,比如P1_0对应LED的IO口。
9 Q8 ~" Z5 k9 F# `# @. f
源代码:6 e: u; ^. S* J' q
  1. #include <reg51.h>4 d9 F: ^% l! [- k: r0 Z
  2. sbit LED = P1^0;
      Q& ]. s% ]" _" J2 L( P; R
  3. void main(){    LED = 0;
    # K7 I: r: d) e3 r! P2 w
  4.     while(1);}
复制代码

' }5 Z* ~* \: f( W- w6 }6 G5 Z. Q% j# t
STM32点灯
相对于51点灯,STM32点灯难度系数要大一点,因为STM32外设资源更多,启动文件更复杂,很多新手看到之后直接就放弃了。
3 V' G6 J4 x3 e# |
其实,也很简单,下面分别通过寄存器标准外设库点灯,你就知道明白了。7 |" \9 L) b4 `9 s( _
准备工作:
  • STM32开发板
  • Keil MDK、ST-LINK Utility下载软件
    + C9 {. E2 B  [" ]& m: O- t

4 m1 ^# E/ Y$ v9 F8 u( d1、寄存器版本! b/ m! A" p4 `9 W& ~- u
直接操作寄存器,需要深入理解每个寄存器每个bit位的含义(不建议初学者一开始就学寄存器),而且,源码看起来比较多:
0 }7 d! a4 L$ j

  1. + w& u5 d/ @# d) {8 m
  2. #include "stm32f4xx.h"
    7 {( q4 L5 U- h' s
  3. # C1 J0 F3 v% G/ d" L" B) ~
  4. /* 主函数*/
    + L$ x1 ?9 M$ N1 h* b
  5. int main(void)8 l+ i" v* o. j" O- U
  6. {2 B  H4 X" n$ g3 f! v
  7.     /*开启 GPIOH 时钟,使用外设时都要先开启它的时钟*/$ O6 x3 ^- Y; o0 y: H. o- ]% O
  8.     RCC_AHB1ENR |= (1<<7);
    2 \% L( i+ w* Q& g* |7 x! x

  9. - Y6 P1 _; s; m1 W
  10.     /* LED 端口初始化 */
    + b' |5 I' [8 L, F
  11.     /*GPIOH MODER10 清空*/. w* u. Y; x6 j3 Y
  12.     GPIOH_MODER &= ~( 0x03<< (2*10));
    5 K  [  A/ e6 |; q/ W  I) z

  13. . {+ w2 O4 U* |5 ~: @
  14.     /*PH10 MODER10 = 01b 输出模式*/
    5 l% M* x. O4 l0 n) {7 w8 b: t
  15.     GPIOH_MODER |= (1<<2*10);  }( o! U  m" v

  16. 5 I+ x( e8 F( o9 D- I# ?
  17.     /*GPIOH OTYPER10 清空*/
    5 M: [/ z4 `, m6 `, {9 ?
  18.     GPIOH_OTYPER &= ~(1<<1*10);9 I, n# S' m7 ]6 |9 O& o& x) ]

  19. ' _4 c. m/ G1 Q2 Z7 Z* J6 L0 L$ H
  20.     /*PH10 OTYPER10 = 0b 推挽模式*/
      u0 U. a) v& o- Z7 P) x( i
  21.     GPIOH_OTYPER |= (0<<1*10);
    . K3 b4 K! E; F0 s6 n1 b: A
  22. * ^' o& i- I" G$ A$ y' v+ |
  23.     /*GPIOH OSPEEDR10 清空*/
    * z* f7 g. Z6 Y& O  f  z
  24.     GPIOH_OSPEEDR &= ~(0x03<<2*10);
    : I: e! \5 Y- l  o

  25. / `" ~+ b: c* h0 ~5 G
  26.     /*PH10 OSPEEDR10 = 0b 速率 2MHz*/2 T" v' M0 K, L2 a- X8 W
  27.     GPIOH_OSPEEDR |= (0<<2*10);
    9 a( R/ @6 e' A4 Z( p% F: `

  28. 1 J& \+ h2 _7 ^4 W. o3 Z9 W% v
  29.     /*GPIOH PUPDR10 清空*/
    * `# T% U9 v) {( b3 @- ^) W
  30.     GPIOH_PUPDR &= ~(0x03<<2*10);
    " I( f0 P6 ]" D. \- @

  31. 7 T- J, U, O9 b& n% ^& K1 X
  32.     /*PH10 PUPDR10 = 01b 上拉模式*/6 I0 V2 \# a4 B% l0 v
  33.     GPIOH_PUPDR |= (1<<2*10);+ e2 z* b: r, |- u

  34. 8 M6 J9 A2 N( G1 _6 V
  35.     /*PH10 BSRR 寄存器的 BR10 置 1,使引脚输出低电平*/
    . z8 l1 ^( T" u* a7 c, y* O
  36.     GPIOH_BSRR |= (1<<16<<10);  //点灯
    ; m9 {+ Q+ z+ ~0 H8 v  |  w

  37. ( o: n7 |; S! N5 N, E) D
  38.     while (1);# C3 Q' z/ O* t8 r8 y5 i9 P
  39. }; W0 e5 S( J9 }
复制代码
1 x% i* t/ B  a) N1 s- G# i+ E, q
! y* d' |2 m; |9 s& x
2、标准外设库版本( ?: `# W' D, h7 x
标准外设库,就是ST官方已经把寄存器进行封装过一次,你直接调用函数借口即可。
  1. #include "stm32f10x.h"
    - t" f6 H* g" G  l

  2. ( F( z% H5 n7 U" K% S
  3. /*  LED时钟端口、引脚定义*/2 ?4 d7 h: b- K/ R: c
  4. #define LED_PORT       GPIOC   
    " P2 ^6 q& E# ^! M9 Q
  5. #define LED_PIN       GPIO_Pin_0
    1 o- W9 e8 s0 {
  6. #define LED_PORT_RCC            RCC_APB2Periph_GPIOC
    ; t* r8 F. v: O. ~3 C+ |: k9 U

  7. ( N3 k2 }# t& t- M0 Q! `- [
  8. void LED_Init()
    4 f6 W6 Q* r0 U! d( j; ?( ?; S
  9. {- `+ _; H- F+ A1 d7 {8 G% o5 Q
  10.     GPIO_InitTypeDef GPIO_InitStructure;        //定义结构体变量
    + Z4 B8 B8 v, J' n" x
  11. 8 H# k: q0 U0 [8 H5 E( F/ v
  12.     RCC_APB2PeriphClockCmd(LED_PORT_RCC, ENABLE);& h+ g# J5 G+ ]* a3 m
  13. # K3 t' u7 k: R. T0 }! v
  14.     GPIO_InitStructure.GPIO_Pin = LED_PIN;                //选择你要设置的IO口
    6 L$ C4 L) @* \1 r" [+ ~2 f( n" o
  15.     GPIO_InitStructure.GPIO_Mode = GPIO_Mode_Out_PP;      //设置推挽输出模式
    & {$ }, R: {7 o9 G" l& Q# [4 A
  16.     GPIO_InitStructure.GPIO_Speed=GPIO_Speed_50MHz;       //设置传输速率/ |5 \6 \. c7 K& }: \! z5 }- l
  17.     GPIO_Init(LED_PORT,&GPIO_InitStructure);              //初始化GPIO 7 ]. [  n5 t& E. v! E
  18. ( R, U# b. f+ G- V: e& @2 D5 h* R6 f
  19.     GPIO_SetBits(LED_PORT, LED_PIN);                       //将LED端口拉高,熄灭LED
    5 J9 F1 H/ x$ Q2 J: Z4 X- c
  20. }3 ~6 @0 t7 H0 C

  21. 6 j. R3 H  ~( s5 o0 r* e6 U$ L
  22. int main()( l- i5 z/ ^; C% O$ ?. ^* k
  23. {  
    9 ^& ?& c8 r  }5 e( K( h+ C
  24.   LED_Init();7 w" Z9 r" t2 }6 V
  25.   GPIO_ResetBits(LED_PORT,GPIO_Pin_0);//点灯
    7 k! [+ S4 c4 L$ @. X

  26. : W( ^* }% z/ ]! a0 u
  27.     while(1);
    / r+ q4 r# h3 x( U0 v6 @7 q
  28. }9 X: ~& `2 k) P6 M3 E, t7 ]2 @3 Y9 ^. p
复制代码

6 o, a2 P1 B" k) C7 }* g" _0 `! f" w5 U1 d$ _  b4 W! h4 K

- Y6 \7 f& E+ M1 |8 ?
Linux点灯
Linux点灯,相对来说就更复杂了。当然,有一些已经搭建好的环境,就相对简单一点,也比较容易。如果自己一步一步移植系统、写驱动···就很复杂。8 b' A$ G4 c9 y: W" g/ i( v5 n

# W# M5 D! l7 j1 N1 f7 Z" L
1、树莓派9 z/ q" A0 s+ ~* i7 v/ s
我们这里以【开源库wiringPi】为例:
  • 下载U-boot源码,配置、编译;
  • 下载Linux内核、配置、编译(一般开发板都会有现成的配置文件);
  • 制作跟文件系统;(以上三个步骤,如果没有一定的Linux基础,可以使用一键烧写)
  • 移植开源库WiringPi;
  • 查看电路图找到LED对应的引脚,程序需要用到引脚号;
  • 编码、交叉编译;
  • 下载运行。
    ; E$ n. a1 g+ t7 l
' G+ E! u) \: y& E+ G
准备工作做好之后,点灯的源码就比较简单:
& v: W* s. ~) O* a3 s
  1. #include <wiringPi.h>
    $ N) W( Q4 ~( i' L
  2. , Z( ~9 ^2 E7 s& B" B6 ]0 m
  3. int main(void)
    % \# i& s' ?( N& w4 T! X
  4. {
    6 \# o3 G/ V& V8 O' J0 W
  5.     wiringPiSetup() ;8 Y6 D2 A8 h0 W+ s  x
  6.     pinMode (7, OUTPUT);
    " I8 b6 l" e9 U" P0 q' z
  7.     gitalWrite(7, HIGH);
    1 D2 h% Y$ P$ n, d4 M3 E7 V
  8.     while(1);) D2 U4 @, p0 z9 l$ s/ e, B
  9. }
复制代码
2 M8 h6 w  R6 p# J; n  l: S0 b

- \  v+ r; C: {6 F9 L8 X1 C+ n- J8 z
2、Linux驱动点灯$ |- V8 a2 e& Q- d  j0 H
在所有的点灯方法中,这个方法难度系数极高,涵盖了嵌入式开发从上层应用到底层驱动。步骤涉及了驱动代码编写、Linux内核模块添加、移植操作系统、Linux应用程序编写* s2 ]( F& t: g3 b7 ]0 Y7 H0 @
这里分享一下mini2440经典LED驱动源码:
; c6 H- n# t) @: l8 i/ W: K
  1. , J+ A2 ?4 s+ S) ^% |2 T
  2. #include <linux/init.h>( E% C  X/ M/ K) H) r  C' S
  3. #include <linux/module.h>
    ; v0 W+ ^/ J- B. _
  4. #include <linux/fs.h>
    3 y; [' C: x8 ~# {
  5. #include <linux/miscdevice.h>
    + G4 N9 ~% A9 S7 Q" O( l
  6. #include <linux/ioctl.h>1 j0 h3 t( x9 I0 a
  7. #include <linux/gpio.h>
    5 K3 M( {; s" `9 Y7 J$ s0 M; k
  8. #include <mach/regs-gpio.h>
    + u/ Q' ?& n5 d
  9. #include "led.h" 1 F3 ~+ V6 k( F3 S
  10. 2 ^* o& [' j# r9 M
  11. static int led_open(struct inode *inode, struct file *file)" O3 c; G# ^% o( u+ F
  12. {  . B+ k1 J3 |* b7 h$ N5 U
  13.     s3c2410_gpio_cfgpin(S3C2410_GPB(5), S3C2410_GPIO_OUTPUT);
    & W  S! s- C3 w! S8 Q
  14.     s3c2410_gpio_setpin(S3C2410_GPB(5), 1);   
    4 G0 J9 s- A* j  e9 F7 K
  15.     return 0;
    6 M  E; w2 T/ s+ E7 O9 T# t2 T8 c
  16. }
    , f4 x  k/ o6 J! H1 k

  17. 9 T% i+ X7 J1 C# p; A% r- f$ l
  18. static int led_ioctl(struct inode *inode, struct file *file, unsigned int cmd, unsigned long arg)* J  m) `6 E. \: z  z& T& H
  19. {  , e5 X/ C. Q4 }4 J$ d+ @) l
  20.     switch (cmd) {  $ i% C/ l1 e& O$ r9 T: r
  21.         case LED_ON:    ) z" I8 {! C. s* k
  22.             s3c2410_gpio_setpin(S3C2410_GPB(5), 0);   
    * T# K9 S4 H4 c4 G8 |
  23.             return 0;  * ~# P/ P. ?$ V2 ^- e
  24.         case LED_OFF:   
    4 d# s( K! v% Y, a* O" `' H( o
  25.             s3c2410_gpio_setpin(S3C2410_GPB(5), 1);   
    * j6 T# X0 Z) y2 q; b0 p
  26.             return 0;  
    4 O8 c6 ?; z' Q! O% C" y: U; o
  27.         default:   
    8 h1 G' L2 Z. `; P* C
  28.             return -EINVAL;  4 l/ ~; y/ N+ i4 M
  29.         }
    ) ?+ D! q& N9 h3 C9 j4 `+ O9 N
  30. }
    9 r5 Q4 [2 k6 O7 c2 c9 s
  31. / J( n' u/ f  @1 n
  32. static struct file_operations led_fops = {  
    & n/ Z8 f/ A1 Y# g* l, M) _% X
  33.     .owner = THIS_MODULE,  ) O! a7 B% R( ~9 |0 Q
  34.     .open = led_open,  7 b, J3 c9 K* K% Z: k9 d
  35.     .ioctl = led_ioctl,
    : Y9 J/ `% W; a, m% E/ g3 s; R
  36. };   x, {% @! [! x4 R/ W3 i. I& {
  37. % o' w; U/ s0 }& \$ Q- T
  38. static struct miscdevice led_misc = {  
    1 }+ L$ o2 R4 v3 C; {$ }0 N
  39.     .minor = MISC_DYNAMIC_MINOR,  . p' t& c7 \8 q3 @2 I5 Z2 l% F" w
  40.     .name = "led",  
    9 I5 ?4 C+ \$ x2 ~1 s
  41.     .fops = &led_fops,
    9 ~) w5 |' Y- T/ F
  42. }; 4 q: B  E6 u3 X
  43. 2 B1 K8 ?/ S' h4 v% @6 T
  44. static int led_init(void){  
    9 s& l  h9 l' B
  45.     return misc_register(&led_misc);! h. @' f) C& {/ ?4 j
  46. } - b9 T; A3 I1 P$ N
  47. ; c! m" V# C3 z* T
  48. static void led_exit(void){  8 e0 z* B$ L) E2 h: [3 Y* U
  49.     misc_deregister(&led_misc);) B: ^3 g9 A: S, W1 C
  50. }
      r3 E9 [" I! B! m+ h& X7 L" p

  51. / B3 }' ~- S, L
  52. MODULE_LICENSE("Dual BSD/GPL");
    $ n) f" N4 I2 W, x
  53. module_init(led_init);
    & j! D, H" j- Y0 T% x" G" T
  54. module_exit(led_exit);
    3 A7 C/ G/ x$ P
复制代码
0 n+ D) ~+ z8 Y1 _, n6 k

' M. X; q  s- j# I2 _2 `

, [4 h- U: r- A$ p2 J6 @驱动写了,然后就是应用层代码:2 ~% n" z& m. Z/ p% Q. j5 X" i! D% c+ i
  1. 3 q4 F2 h. M/ R' C) q
  2. 3 {+ r9 }1 k' E- j
  3. #include <sys/types.h>
    ! |& h' J. R# ]+ w( Q) J+ L
  4. #include <sys/stat.h>, C7 B8 I9 V& ]+ j' [& n( \0 C! O7 }
  5. #include <fcntl.h>) r4 c: Q$ T' B, R9 B) k& w
  6. #include <sys/ioctl.h>5 ?% O5 ]2 U* O
  7. #include <unistd.h>; \- m  d  `3 Q, r/ J. ~& N6 h6 K
  8. #include <stdio.h># U% m7 ^- q& {$ U+ Y4 M  x
  9. #include "led.h"
    0 Q% L% A' ?! Q2 M* d- L
  10. ; S% T, \, X) @# D/ Z) b9 n
  11. int main(void){        
    3 p8 S2 S5 y; s  ]
  12.     int fd;         9 c; b4 I7 n! J' B/ |1 a
  13.     fd = open("/dev/led", O_RDWR);         
    % U. T, E7 G0 i! C- U( b) h1 b
  14.     if (fd < 0) {                1 ^1 k5 o% T5 i
  15.         printf("No such device!\n");               
    4 i/ p. M# V; u, X4 T
  16.         return -1;        / J+ V9 l& ]2 G
  17.     }         
    / c1 l: L- {- `) c
  18.     while (1) {               
    3 r* J' J% n, r( y- x, s0 B; n
  19.         ioctl(fd, LED_ON);                # r+ V$ l3 q) ^! ?4 l2 H8 k. \2 U
  20.         sleep(1);                $ \: H$ J9 g( T: r5 c; D
  21.         ioctl(fd, LED_OFF);               
      M* T. _1 V, ?9 \
  22.         sleep(1);        
    4 w4 s6 p4 C/ U- c
  23.         }           E8 U) Z+ C. A3 Z- n  p0 M
  24. 4 a8 X3 P0 I5 L2 i% n5 ~# S' N
  25.     close(fd);         2 J9 t6 T) q9 E. t' H! n5 R
  26.     return 0;) d9 S: o& ~# {7 ~4 M; V8 l# S
  27. }
复制代码
4 Z8 ?, e+ |' a. Q& J! @5 n

7 F2 Q! f2 `4 x% D
8 Y; W* E& q$ j0 t3 d* b2 \7 M

) K/ J# h1 o1 x" }1 T( V
收藏 评论0 发布时间:2022-3-17 18:04

举报

0个回答

所属标签

相似分享

官网相关资源

关于
我们是谁
投资者关系
意法半导体可持续发展举措
创新与技术
意法半导体官网
联系我们
联系ST分支机构
寻找销售人员和分销渠道
社区
媒体中心
活动与培训
隐私策略
隐私策略
Cookies管理
行使您的权利
官方最新发布
STM32N6 AI生态系统
STM32MCU,MPU高性能GUI
ST ACEPACK电源模块
意法半导体生物传感器
STM32Cube扩展软件包
关注我们
st-img 微信公众号
st-img 手机版