【学基1】单片机方向C语言期末复习重点:从语法到外设控制

7 0
EDGE 发表于 2026-8-26 00:28:13 | 查看全部 阅读模式

马上注册,结交更多好友,享用更多功能,让你轻松玩转社区。

您需要 登录 才可以下载或查看,没有账号?立即注册

×
单片机方向的 C 语言学习,和普通教材里的语法练习不同:代码最终要控制 LED、蜂鸣器、LCD 或传感器。只背语法容易出现“看得懂例题,但不会写项目”。下面结合单片机报警程序整理期末复习重点。
一、变量和数据类型
3 G- u9 s* W/ F6 C
程序需要保存传感器采样值、计数值、延时时间和报警状态。常见写法是:
  1. unsigned int gas_value;3 ]9 O1 X2 f/ _: @/ P
  2. unsigned char count;
    3 r2 c) s9 [3 L9 B: i+ z& L+ U& Z1 L
  3. bit alarm_state = 0;
复制代码
unsigned char 适合保存 0~255 的小整数,unsigned int 常用于 ADC 采样值和计数值,bit 适合保存开关量。不要为了方便把所有变量都定义成 float,8 位单片机中浮点运算会增加资源消耗。
二、条件判断是报警程序的核心" O- S: V4 n  J: z
  1. if(gas_value >= 650)! l9 i4 J+ O% ~2 E; F
  2. {+ Q; ?: Z7 ~& P
  3.     BEEP = 0;7 K5 K+ ^7 P( j. N
  4.     LED_ALARM = 0;
    ' b; ^9 p: C: M8 e+ H* C) Z0 _
  5. }4 S* B8 b4 S, D. R/ ]: w
  6. else
    ) O$ C; k, f6 e# N' V! M% J4 W
  7. {
    1 d, A% B& q* o+ t+ P$ f: h. D
  8.     BEEP = 1;; H) S4 u4 T. @0 k: Z
  9.     LED_ALARM = 1;! S! j! L: I$ m4 a5 O
  10. }
复制代码
需要注意,部分电路采用低电平有效方式,代码中的 0 不一定代表关闭,1 也不一定代表打开。因此端口逻辑必须结合原理图确认。建议将输出动作封装成函数。
  1. void alarm_on(void)7 B+ K" V6 ^5 [$ u0 S8 p) P
  2. {& b: o( ^! `; ~
  3.     BEEP = 0;
    - Y/ f2 `* [& T% m% v
  4.     LED_ALARM = 0;
    # a; X  _4 X6 r* G) z
  5.     RELAY = 0;
    * V2 S4 f/ K1 b/ N  _& t" `
  6. }, d1 u1 i6 U1 A. s( `
  7. & `2 c% }$ G0 t, G  g
  8. void alarm_off(void)
    5 T* ?" A1 l) v! Z" ^3 [6 K0 X
  9. {7 i. V* H' u4 f; S9 E
  10.     BEEP = 1;$ g' o# J8 v- E( G
  11.     LED_ALARM = 1;6 |! q0 d" J5 l3 q
  12.     RELAY = 1;
    / W$ y7 K9 l3 F/ C
  13. }
复制代码
三、while 循环和主程序结构( O' e! X$ b  X. l8 t
  1. void main(void)4 k% a$ b3 R: F
  2. {
    % t2 a' a2 p, H& x0 x& P3 [
  3.     system_init();
    & x, G( C8 y5 j; w
  4.     while(1)* E  \3 C2 a/ v& A0 Q1 k! q5 g
  5.     {9 D5 B/ ~7 _. Q) K
  6.         gas_value = adc_read();; E% B0 w" M1 p1 F. p5 L
  7.         lcd_display(gas_value);3 Z  P4 B2 _: R
  8.         gas_check(gas_value);
    % i6 x& l4 ^  Y6 Z
  9.         delay_ms(100);3 g% d' X+ t- J! Z4 l
  10.     }
    1 B" g$ A, a8 {; ]7 u5 q
  11. }
复制代码
主循环一般可以拆成读取、显示、判断和等待四步。没有 while(1) 时,程序只会检测一次,仿真中会表现为数值不再更新。
四、函数封装, ?6 L& k$ k3 f
建议把 LCD 初始化、ADC 读取、报警控制和延时分别写成函数。这样主程序更清晰,出错时也容易定位。
  1. void lcd_init(void);
    * n  R# {2 k3 B4 i" l; o0 l; j
  2. void lcd_display(unsigned int value);
    % Z7 Q  {. s6 e- E" w- \; w! F
  3. unsigned int adc_read(void);
    $ D) B# D3 L& }: D" r8 ]
  4. void alarm_on(void);4 U- |3 v7 j' {1 j( E& U0 @
  5. void alarm_off(void);3 _. x' `4 e! l5 p8 }
  6. void delay_ms(unsigned int ms);
复制代码
五、数组和字符串
9 v' A( Q0 i& z# K5 c' g: K
  1. unsigned char message[] = "GAS WARNING";
    5 E; X7 l* B  P3 ~

  2. : y& q! ^3 G* Y
  3. void lcd_show_string(unsigned char row,$ F" k6 O) N1 I2 u
  4.                      unsigned char col,
    , P0 _* G# H* s5 \& Q8 Y' M5 w
  5.                      unsigned char *str)
    ' P& M8 R" P- n$ v- \% o
  6. {7 i, A) c- y/ i8 O+ U7 O) g! S
  7.     while(*str != 0)! p) g2 i+ f- b; N, E+ ^
  8.     {  v" Y! |1 N/ z4 K& c5 M0 l
  9.         lcd_write_data(*str);* |' h' A2 ~. A
  10.         str++;
    . i- E( L$ [) Y1 l# I4 o
  11.     }
    " a' c6 m9 @& q' C/ k- x  u1 v
  12. }
复制代码
# f) o) T) D4 R$ r
字符串以 '\0' 结束。忘记结束标志时,程序可能继续读取后面的内存内容,造成 LCD 显示乱码。
六、ADC 采样值处理
9 }8 t# O' F: Z2 [8 ^& O4 m) v
  1. unsigned int adc_read(void)6 ?: a+ ^: a6 a% a
  2. {
    & H1 n8 S1 Y' Q( u1 |+ t7 t
  3.     unsigned int value;
    + \9 S& b$ m" l
  4.     ADC_START = 1;$ ]8 U3 l& I5 V9 k7 e$ {
  5.     delay_us(10);
    / P) s; T/ h8 H5 `, W4 l0 B
  6.     ADC_START = 0;, `2 [+ J2 T/ c
  7.     while(ADC_BUSY);
    / }  ?) `7 o7 j6 Y" e7 `  U% y$ A" v
  8.     value = ADC_HIGH;
    3 f( Q4 K5 E& m$ p- t0 P8 x
  9.     value = (value << 8) | ADC_LOW;
    * `: y- n: r) p% X. N& ]/ P
  10.     return value;
    % Y+ x; g! l2 z6 d  ~- {2 I
  11. }
复制代码
3 [) O7 M& {- c4 Y6 D5 q, c; |
如果 ADC 是 10 位,数字范围通常是 0~1023;如果是 8 位,范围通常是 0~255。复习时必须先确认 ADC 位数,不能直接套用公式。
七、常见错误
7 _2 Y/ F! l8 ]( z% t3 \
第一,把赋值写成比较:if(alarm_flag = 1) 是赋值,应写成 if(alarm_flag == 1)。第二,变量未初始化就参与判断。第三,忽略端口有效电平。第四,LCD 未初始化就调用显示函数。第五,延时参数过大导致程序长时间停在延时函数中。
八、综合例题& `2 q$ c$ ~  W7 X& v: y% n1 O
题目:读取气体传感器,当检测值大于 650 时启动蜂鸣器和红色 LED,否则关闭报警。
  1. $ v! ~5 L$ m& u3 H' U; F  n
  2. #define GAS_LIMIT 6504 N# o7 z8 q6 J/ d8 P9 A0 y( Q6 w* f
  3. sbit BEEP = P2^0;0 N# [9 W! w9 S' x9 [; b$ H
  4. sbit LED_RED = P2^1;$ }8 ~3 ?+ Y! O' x

  5. , w: l( Z3 V7 L& V# @* E
  6. void main(void), ~0 K, i+ G& B4 F
  7. {# U' N' K( m" t+ H
  8.     unsigned int gas_value;
    3 p4 d/ G% _/ ?  e0 N% c7 O
  9.     lcd_init();2 m4 D( o2 `/ s, Q& ]7 l9 z8 }- p9 J
  10.     BEEP = 1;( }- l! u3 g. M! e  k
  11.     LED_RED = 1;
    $ u3 r6 U. z. k" D* |
  12.     while(1); z7 v9 X. b8 i$ N% F4 `* V, V
  13.     {
    & ~4 |8 ]5 Q: i: m3 `
  14.         gas_value = adc_read();
    : ~$ L' K( R2 h6 E9 n
  15.         lcd_display(gas_value);5 `' b. b  }" P& p9 s
  16.         if(gas_value >= GAS_LIMIT)4 p/ P- M) F% |" H3 e1 i
  17.         {
    % `. {2 O1 b3 F6 `
  18.             BEEP = 0; LED_RED = 0;
    ! e7 b9 [9 x6 R! v  `% a- v' |$ a* d! a) e
  19.             lcd_show_string(1, 1, "DANGER");( \9 x$ A3 V: U
  20.         }
    * a+ t- r4 J5 Q$ l  X! u
  21.         else; ~) ?* p, }' |5 Q2 i
  22.         {
      [/ r1 `% b& [* V
  23.             BEEP = 1; LED_RED = 1;
    , Q. k6 [& I6 O8 j* _
  24.             lcd_show_string(1, 1, "SAFE  ");- g: C* ]& E# L8 C; S8 x
  25.         }4 {4 c% f/ z4 T4 ?5 j6 ^, i
  26.         delay_ms(200);$ T8 I1 x5 r2 X
  27.     }
    2 d& \' k3 B' S8 y1 M
  28. }
复制代码
) w) u# a$ r; R0 G1 x
九、复习建议8 {4 ^6 r6 ]& O; }. f/ J
单片机 C 语言不适合只背定义,建议按照“语法—代码—仿真现象”的顺序复习。复习 if...else 时同步看报警控制程序,复习函数时分析 LCD 初始化,复习数组和字符串时结合 LCD 显示。遇到错误时,通过仿真现象反推问题位置。
总结
6 x* V2 I- v" \9 H7 d
单片机方向的 C 语言重点集中在变量、条件判断、循环、函数、数组、端口控制和传感器数据处理。真正写项目时,难点不是单个语法,而是把多个知识点组合成“采集—判断—显示—执行”的完整流程。

. a; b# \3 t6 r4 ^0 N- U3 ~8 B
2 Z0 `: l7 m$ r& }, h( G3 D
回复 转播

使用道具 举报

回复

您需要登录后才可以回帖 登录 | 立即注册

本版积分规则

学研领航向全体高校师生打造的一站式综合交流与资源服务平台,集知识学习、经验分享、资源下载、互动问答、职场成长、兼职实践于一体,覆盖校园生活、专业学习、求职就业、兴趣发展等全场景需求。

快捷导航

小黑屋
Copyright © 2026 学研领航 版权所有 陕ICP备2025077879号-1
关灯 在本版发帖 返回顶部
快速回复 返回顶部 返回列表