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

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

[复制链接]
STMCU小助手 发布时间:2022-3-17 18:04
嵌入式初学者入门的第一个“项目”就是LED点灯,那么,本文带你看看51、STM32、Linux点灯有什么区别?
! N& Y+ d' C9 E3 M
51点灯
51点灯,是很多单片机初学者的首选,难度也是相对比较低的。
( H/ w8 U- \, n$ d
准备工作:
  • 51开发板(以STC51单片机为例)
  • Keil C51、STC-ISP下载软件4 D7 M+ {. `* `7 u6 N* d, J3 n
    9 ]4 a, X- R/ z5 Z1 x# y  z

) s- j$ h: N" u2 L51单片机开发,通常是直接操作寄存器,比如P1_0对应LED的IO口。
- e0 a. |6 s7 Y3 U- S7 Y+ @+ b
源代码:% m: H1 c% d4 [& S
  1. #include <reg51.h>9 M9 z& U. N; q" O1 J# X& k, Y
  2. sbit LED = P1^0;7 h9 ?1 Q2 E6 g. L' ]6 e5 p" `
  3. void main(){    LED = 0;
    * `9 y# R- |$ Q
  4.     while(1);}
复制代码
! u0 g3 A$ ~' I( G" o* {* R0 R) g
STM32点灯
相对于51点灯,STM32点灯难度系数要大一点,因为STM32外设资源更多,启动文件更复杂,很多新手看到之后直接就放弃了。* l8 d7 k, w' A  [9 j6 I9 q
其实,也很简单,下面分别通过寄存器和标准外设库点灯,你就知道明白了。
4 N( W( s+ `; n. d  m. d准备工作:
  • STM32开发板
  • Keil MDK、ST-LINK Utility下载软件
    ; w# ~; a* G0 \& i6 v
! a, X, C3 ]( j0 d
1、寄存器版本
4 c. C  r8 z7 u  ~9 q+ n9 C直接操作寄存器,需要深入理解每个寄存器每个bit位的含义(不建议初学者一开始就学寄存器),而且,源码看起来比较多:
3 W- W2 C8 G+ Z  L) d
  1. 3 H# ]: y7 p- g+ t
  2. #include "stm32f4xx.h"
    2 P0 M9 r6 X* k# w! _

  3. 9 \2 I& @/ P! V" a! B8 r) y! k
  4. /* 主函数*/
    # F: J, L- w" I. O
  5. int main(void)- o( t9 E" i2 [+ Q
  6. {5 W) Z. d' o  H2 Z' R, S
  7.     /*开启 GPIOH 时钟,使用外设时都要先开启它的时钟*/; x) t4 O8 x4 o( r2 n5 u. P
  8.     RCC_AHB1ENR |= (1<<7);6 u/ m# ?/ @! j' {1 ~
  9. " [/ R( B( p, M1 L
  10.     /* LED 端口初始化 */
    8 e- Z* z3 [* z- ~! D
  11.     /*GPIOH MODER10 清空*/
    % u$ ]: O& f0 E) a; l% O. r: \
  12.     GPIOH_MODER &= ~( 0x03<< (2*10));5 v# q7 t- |" W
  13. 8 ?: }- `, y5 Y4 j
  14.     /*PH10 MODER10 = 01b 输出模式*/
    3 d1 x! Q4 o( O8 x% d0 c' U
  15.     GPIOH_MODER |= (1<<2*10);
    ; I/ L" U( f" _) D' }% y

  16. 1 X% \& ~+ ~, z+ S) d
  17.     /*GPIOH OTYPER10 清空*/
    7 S7 y* N1 R+ R: Q, R
  18.     GPIOH_OTYPER &= ~(1<<1*10);
    : ~/ R) Q: _: K0 w6 P5 h0 S7 g

  19. * U: f" q& S6 p+ w
  20.     /*PH10 OTYPER10 = 0b 推挽模式*/# s) A; Y2 M6 H1 I1 x: ?
  21.     GPIOH_OTYPER |= (0<<1*10);! _6 H( Q, @1 `. m% T5 z$ R
  22. 6 G" F' E4 }! l3 @4 T
  23.     /*GPIOH OSPEEDR10 清空*/' k* W9 [  ]0 k5 X, F" n0 q7 x0 h
  24.     GPIOH_OSPEEDR &= ~(0x03<<2*10);
    0 d. a# I8 p0 s# Y) J
  25. 0 e( w, ?  a& G8 K0 V( {
  26.     /*PH10 OSPEEDR10 = 0b 速率 2MHz*/' b, E4 W$ P5 \, P& ]
  27.     GPIOH_OSPEEDR |= (0<<2*10);
    $ J4 \+ {3 b( P# m( k  ?

  28. 5 {  s7 V' `0 h& w" C
  29.     /*GPIOH PUPDR10 清空*/
    7 H, `, H& j4 c' N- H0 T
  30.     GPIOH_PUPDR &= ~(0x03<<2*10);
    1 _1 }8 b, p6 e1 O( a  m
  31. + u5 H2 I' Y2 {+ m2 V1 M- N
  32.     /*PH10 PUPDR10 = 01b 上拉模式*/! r' M# f9 D, H! X. b& x9 P
  33.     GPIOH_PUPDR |= (1<<2*10);5 R+ W* k2 N& U/ Z! x

  34. 1 y5 t; Q/ z, o: \: u
  35.     /*PH10 BSRR 寄存器的 BR10 置 1,使引脚输出低电平*/* }& H$ _  j" s1 ~/ l: }
  36.     GPIOH_BSRR |= (1<<16<<10);  //点灯( A( T0 u# o# W( s' _

  37. . I% ~+ ]' `. N
  38.     while (1);
    . U# d+ [& l. k
  39. }
    , p/ T  K1 g! |" I% X) m$ O) E: n
复制代码

- L6 a3 x; O0 I( t! Q5 S
# P& S; s0 n+ s) E3 Y! H' i2、标准外设库版本" A) ^  f) v- K- e4 c6 H
标准外设库,就是ST官方已经把寄存器进行封装过一次,你直接调用函数借口即可。
  1. #include "stm32f10x.h"
    : e; r( y( n3 D3 r7 g2 k$ n

  2. " c' }* J& j; V9 }
  3. /*  LED时钟端口、引脚定义*/2 k5 ~4 ?0 V, h" q; F
  4. #define LED_PORT       GPIOC   % _- e3 J- C& M! \, v
  5. #define LED_PIN       GPIO_Pin_0
    3 C4 i+ M, y) C" D9 [* U9 `
  6. #define LED_PORT_RCC            RCC_APB2Periph_GPIOC0 }# M& _" d% j' o) C4 M/ |
  7. ; {; g: p  d$ k& u& Y0 M/ \3 }
  8. void LED_Init()
    , v/ e1 |7 p4 E' o) u
  9. {, i/ l' r+ g7 B3 u
  10.     GPIO_InitTypeDef GPIO_InitStructure;        //定义结构体变量" H9 E9 e6 u5 L) T4 c

  11. , R! Z' ?. z, J& H7 @. L
  12.     RCC_APB2PeriphClockCmd(LED_PORT_RCC, ENABLE);
    5 M' s# P8 l; B

  13. 5 z- ]+ \& \& C0 z' `' s3 u0 u' \
  14.     GPIO_InitStructure.GPIO_Pin = LED_PIN;                //选择你要设置的IO口/ `  f0 a( Q& z1 h5 [" G6 }
  15.     GPIO_InitStructure.GPIO_Mode = GPIO_Mode_Out_PP;      //设置推挽输出模式
    1 W! J! _! F9 a2 u
  16.     GPIO_InitStructure.GPIO_Speed=GPIO_Speed_50MHz;       //设置传输速率
    4 m: R' o8 ~0 R: w+ t: T
  17.     GPIO_Init(LED_PORT,&GPIO_InitStructure);              //初始化GPIO
    . I5 N6 @1 [' L

  18. 2 Y8 K1 E. r4 u3 K: ?
  19.     GPIO_SetBits(LED_PORT, LED_PIN);                       //将LED端口拉高,熄灭LED( ^9 q; f. N9 k- t6 r
  20. }8 g% G0 F- F/ r# C

  21. ( \. U$ C: X5 z  n
  22. int main()* u+ j3 [* t3 \# V( s
  23. {  ) p! m; C( H8 J) f" f
  24.   LED_Init();
    9 g, ]! t0 b' c3 b" N; `1 R
  25.   GPIO_ResetBits(LED_PORT,GPIO_Pin_0);//点灯. f  |" `, f7 {/ I( X
  26. 2 h5 H9 y9 k1 |5 B
  27.     while(1);
    4 c% \& s# v9 B3 O
  28. }
    " R2 z$ y0 j4 b. [' n
复制代码
/ E( K: M! k: |" A) k

; w# ]5 l- s1 y( L& K3 D0 R( q$ S" A8 [
Linux点灯
Linux点灯,相对来说就更复杂了。当然,有一些已经搭建好的环境,就相对简单一点,也比较容易。如果自己一步一步移植系统、写驱动···就很复杂。
+ [, |0 x# J( Y6 z# I) B
0 o" @6 b# x; g- ]" m. P/ g, d
1、树莓派7 [+ r7 b  |9 c9 H; ^! c
我们这里以【开源库wiringPi】为例:
  • 下载U-boot源码,配置、编译;
  • 下载Linux内核、配置、编译(一般开发板都会有现成的配置文件);
  • 制作跟文件系统;(以上三个步骤,如果没有一定的Linux基础,可以使用一键烧写)
  • 移植开源库WiringPi;
  • 查看电路图找到LED对应的引脚,程序需要用到引脚号;
  • 编码、交叉编译;
  • 下载运行。
    1 _2 A+ Y4 C4 d  J

4 E  I, K* K# a8 G
准备工作做好之后,点灯的源码就比较简单:& [; T: W5 e. x  \) W3 e, c
  1. #include <wiringPi.h>
    " v1 t3 @! ]5 ]5 |4 B( r5 F

  2. ! Z7 L4 N- m0 n1 L
  3. int main(void)
    3 o) B4 i4 x8 d
  4. {/ v1 z  m8 ~' Y  U
  5.     wiringPiSetup() ;
    , e3 u, F* _, m5 |
  6.     pinMode (7, OUTPUT);# ~" t1 }0 K# C+ }7 ]
  7.     gitalWrite(7, HIGH);
    " L3 c& q) c/ [( H8 C. X
  8.     while(1);6 o+ @- W' k. X/ V, G* i/ V
  9. }
复制代码
, n' ^( _) F7 u: L0 I' C- W3 R

" C& Q0 n( s. V2 ^4 U/ s: M1 N# v) Q) e  w# x( F9 m' j
2、Linux驱动点灯! u/ ^- ^0 R. i3 @* @( B* b
在所有的点灯方法中,这个方法难度系数极高,涵盖了嵌入式开发从上层应用到底层驱动。步骤涉及了驱动代码编写、Linux内核模块添加、移植操作系统、Linux应用程序编写。 " f, d. y& U! j2 s
这里分享一下mini2440经典LED驱动源码:$ T  a- N- q) q' k

  1. 8 t( X3 P/ v* \# }& U7 q& D
  2. #include <linux/init.h>( ^! e3 V  \( l8 a
  3. #include <linux/module.h>
    . j5 M  P- n/ n
  4. #include <linux/fs.h>* o4 v! s2 U4 d1 d
  5. #include <linux/miscdevice.h>6 x! p& n$ M; d, M' f9 W( B
  6. #include <linux/ioctl.h>7 M, t0 o) S0 L. q- C$ R" p
  7. #include <linux/gpio.h> - r  a: h- `2 a
  8. #include <mach/regs-gpio.h>
    9 P4 N* s) H3 s0 [  {# x
  9. #include "led.h" ! t7 S8 |' ~/ R4 z* h( x
  10.   C0 E8 j8 o5 C. o! K
  11. static int led_open(struct inode *inode, struct file *file)& O" L! K* J& R% s/ O
  12. {  ' Y7 b: ?! n9 J
  13.     s3c2410_gpio_cfgpin(S3C2410_GPB(5), S3C2410_GPIO_OUTPUT);4 C4 S6 |' I& _9 j
  14.     s3c2410_gpio_setpin(S3C2410_GPB(5), 1);   
    ' r' W9 |; W/ g% @8 c  a/ O8 P
  15.     return 0;
    " S& z! J& L5 k
  16. }
    1 P; s8 x' I: U" L7 _. k2 ]

  17. 9 Q; ], z; P; X
  18. static int led_ioctl(struct inode *inode, struct file *file, unsigned int cmd, unsigned long arg)0 b' m2 W/ n$ i1 k0 V/ R
  19. {  
    ; P- Y( c& v- Y' N; b& |1 z6 j
  20.     switch (cmd) {  ( w% y1 q8 f5 V# }
  21.         case LED_ON:   
    % j9 @9 d. [6 w5 F5 O% q; f/ g1 t9 ?
  22.             s3c2410_gpio_setpin(S3C2410_GPB(5), 0);   
    + D4 l: h% f" g5 m! R* @
  23.             return 0;  
    6 ?. A' F* Z" @
  24.         case LED_OFF:   
    1 |; M8 @9 D6 y
  25.             s3c2410_gpio_setpin(S3C2410_GPB(5), 1);    % o8 `) J* x2 I* Q
  26.             return 0;  
    ( f) w% T) n9 k7 D$ X$ v
  27.         default:    + C3 ?6 N3 ?" M: a' z. ^
  28.             return -EINVAL;  
    4 A# |" U4 i- f
  29.         }7 E$ m8 G' j: \4 K+ g  `- ?
  30. } : G3 j, _4 P" m) D* u: X9 t
  31. 0 L0 [% @  b2 ^- H! k  Z0 ?9 E
  32. static struct file_operations led_fops = {  
    ! Q# L- D. {( z1 P6 ?
  33.     .owner = THIS_MODULE,  4 p# y# K9 [( P. l
  34.     .open = led_open,  
    6 v; `# {. m. a$ G3 M
  35.     .ioctl = led_ioctl,# _5 b2 R0 {1 A' K, t  u* T
  36. }; ! G9 B# {& e8 f+ y! b
  37. : r% \+ M' k  k  I
  38. static struct miscdevice led_misc = {  
    8 Z- x4 |8 ]0 i" w: P
  39.     .minor = MISC_DYNAMIC_MINOR,    \! ^# F5 ^, S. Y( r
  40.     .name = "led",  0 m, v, D; h) m% k, a* P% a5 B5 `- h
  41.     .fops = &led_fops,
    1 V" |/ F+ B8 _; p& `- j
  42. };
    $ B# B$ ?- H% I6 [: M; J0 S  R* M
  43. 1 t) Y, J/ \8 b0 {: Z$ ?& w
  44. static int led_init(void){  
    7 d( w, ~$ E3 p, A. _
  45.     return misc_register(&led_misc);& d- W6 U1 i0 M
  46. } 6 F, U' ^7 K8 G: K

  47. 2 U9 X* I' j  B3 Q; c
  48. static void led_exit(void){  . L. {# F4 V  ~( Q
  49.     misc_deregister(&led_misc);
    " C7 Z5 u; D2 d& z
  50. }
    / C9 ^+ Q. ]0 x
  51. $ V3 K6 M, f, t  [* k
  52. MODULE_LICENSE("Dual BSD/GPL");
    ! j6 c( X; F. Y- s
  53. module_init(led_init);) p3 B. U6 ^7 ]+ z
  54. module_exit(led_exit);
    8 l6 O6 m. l/ }" R* N+ ~9 S
复制代码
- [' t9 ]4 _7 p& ^' _
$ f+ Q1 a" H& Y/ n* D

% b4 u( y/ {, D* P3 W驱动写了,然后就是应用层代码:. {" T8 R( h6 M- E; M: N
  1. 4 s; R) `( }/ J, R& n0 ~/ x, t( y

  2. 4 j1 I% H+ w; h8 X  T6 Q2 z& r# {
  3. #include <sys/types.h>$ y* ]* P8 E! t$ f
  4. #include <sys/stat.h>6 r3 O: J$ i- t" b
  5. #include <fcntl.h>
    1 F9 p$ F$ x5 B9 E3 b
  6. #include <sys/ioctl.h>
    ! N9 H% U$ a4 ^( q
  7. #include <unistd.h>
    * Q) J0 Y( n3 Q' ^# _( J
  8. #include <stdio.h>
    ) [; _1 N4 u0 T0 S
  9. #include "led.h" : h! P4 y+ u: I9 \2 k# ]9 i2 G9 f( ^7 o
  10. % A2 e" G: d5 s6 B
  11. int main(void){        0 g2 ^5 X3 k" e, n8 k9 [
  12.     int fd;         
    % U# f% i$ s3 e" S
  13.     fd = open("/dev/led", O_RDWR);         
    0 s+ l5 P2 U3 X$ F1 `- P
  14.     if (fd < 0) {               
    . n$ Q( w$ [6 Z0 S8 m" }+ C
  15.         printf("No such device!\n");                8 D0 s4 d1 Q# [& S, ?# M. c
  16.         return -1;        
    3 j3 S3 n* O) Y6 E2 ]
  17.     }         ; z$ [# t4 @) w$ M( i3 N. ^
  18.     while (1) {               
    / |5 Y  G$ C+ c+ R  H# B
  19.         ioctl(fd, LED_ON);                4 E+ C) o- r. M1 A
  20.         sleep(1);                5 d0 m  c! s  T% y) ^/ f- v
  21.         ioctl(fd, LED_OFF);               
    ! p6 N. f  a0 I% o
  22.         sleep(1);        
    + {- m3 j3 N. w8 h" t+ K1 R3 ^6 g
  23.         }         * w8 T) P! P; @8 C$ Z

  24. * ~' J) g" `2 `. f
  25.     close(fd);         
    ) q, v! _1 O4 K  g9 K
  26.     return 0;5 F: k* C, t* y+ q3 Z) S  R
  27. }
复制代码

: E2 V9 B, e; U

) Z/ f( E$ A' U; D8 @
7 K) a% P0 A) ?) ]7 v8 _/ s$ m+ v

; J: G1 O- q6 u6 w8 n
赞 收藏 评论0 发布时间:2022-3-17 18:04

举报

0个回答

所属标签

相似技术帖

官网相关资源

关于
我们是谁
投资者关系
意法半导体可持续发展举措
创新与技术
意法半导体官网
联系我们
联系ST分支机构
寻找销售人员和分销渠道
社区
媒体中心
活动与培训
隐私策略
隐私策略
Cookies管理
行使您的权利
官方最新发布
人形机器人运动控制、感知与智能配电
半导体创新技术与应用方向
EE架构与软件定义汽车
12V/48V 汽车智能配电(SPD)
区域控制单元(ZCU)与分区架构
关注我们
st-img 微信公众号
st-img 手机版