论坛风格切换切换到宽版
  • 3434阅读
  • 11回复

请教关于单片c的问题 [复制链接]

上一主题 下一主题
离线xjl
 
发帖
1244
只看楼主 倒序阅读 0楼 发表于: 2008-08-16
看了不少朋友都在用avr,也想学习学习,并想从此抛弃汇编也使用高级的c.
这两天找了两个简单的例程看了一下,有点疑惑向坛内大侠请教.
c语言又称为函数语言,某一个功能可以用一个函数来完成,当用到这个功能时可以调用这个功能函数.这样问题来了.比如调用led数码管显示函数使数码管显示,然后再调用其他函数完成其他功能,如果有多个其他功能函数要调用,并执行时间超过0.1秒,这样就会造成led数码管闪烁.编译器在编译时会自动处理类似问题吗?还是象汇编一样要每0.1秒内要调用一次led显示子程序? 或采取其他措施?
谢谢
在线BG4UVR
发帖
11288
只看该作者 1楼 发表于: 2008-08-16
首先,编译器并不会去自动处理。

深入一点,其实这并不是语言的区别,就算是使用汇编也一样会碰到这种问题。对于时间上要求严格的步骤,比如数码管的扫描,一般是要放在定时器中断中去执行的。
离线BG4XDO
发帖
1124
只看该作者 2楼 发表于: 2008-08-16
可以考虑用静态驱动
离线xjl
发帖
1244
只看该作者 3楼 发表于: 2008-08-16
哦,明白了,谢谢
离线albert
发帖
4807
只看该作者 4楼 发表于: 2008-08-16
跳出单片机来说这个问题那就是多线程/多进程编程。而且对实时性要求高的那种~~
离线hahamm
发帖
19
只看该作者 5楼 发表于: 2008-08-22
avr运行很快,多位数码管用循环显示,一位有2毫秒可以了,在2毫秒内可以运行其他函数,例如按键处理等,就看程序总体安排了。
离线小比尔/5
发帖
2582
只看该作者 6楼 发表于: 2008-08-23
搞个rtos
离线xjl
发帖
1244
只看该作者 7楼 发表于: 2008-08-25
'
avr运行很快,多位数码管用循环显示,一位有2毫秒可以了,在2毫秒内可以运行其他函数,例如按键处理等,就看程序总体安排了。
'
我很菜,刚刚接触c,所以不是很懂,如果用汇编能理解,但是用c还是不很理解.是否每显示一位后跳出显示函数,执行其他函数,然后循环执行显示函数显示下一位?
离线xjl
发帖
1244
只看该作者 8楼 发表于: 2008-08-25
[quote=小比尔/5]搞个rtos[/quote]
老大不要笑我,我真的不懂.能讲的通俗一点吗?
离线小比尔/5
发帖
2582
只看该作者 9楼 发表于: 2008-08-25
'
老大不要笑我,我真的不懂.能讲的通俗一点吗?
[表情] [表情]
'

不好意思,卖弄了。
其实c用好了比汇编简单,汇编老要研究怎么传递参数,c可以直接利用参数来传
比如说

假设有个动态显示的函数(右侧用汇编类比):
void display(unsigned char num);  // display: mov p0,a/ ret
一个扫描的函数:
unsigned char scankey();  // scankey: .../ ret
一个延时函数:
void delay();  // delay: mov r2,#xx .../ djnz ... /ret

那么你可以这样:
while(1)  // 主程序循环  main:
{
  unsigned char i,key;
  p2=0x80;  // mov p2,#80h
  for(i=4;i>0;i--)  // 显示循环  for:
  {
    display(...);  // 显示一位  mov a,.../ acall display
    key=scankey();  // 扫键  acall scankey/ push acc
    delay();  // 延时  acall delay/ pop acc
    if(key!=0) key=scankey();  // 键消抖 jz main0/ acall scankey / main0:...
    switch(key)  // ...
    {
      case up: addnum();break;  // 加1  cjne main1/ acall addnum
      case down: ...;break;  // ...  main1: cjnz main2/ acall ...
      case left: ...;break;  // ...
      case right: ...;break;  // ...
      case ...
      default: break;
    }
    p2=p2>>1;  // 字位码右移  // mov a,p2/ rl a/ mov p2,a
  } /* for */  // djnz r5, for
}  // ajmp main

整个流程和汇编其实是一样的,这个过程由你自己安排。当然,处理按键的时候,显示扫描就会受到影响。

所以如果要处理和动态显示互不影响,就要把显示放到中断去,当然也可以用移位寄存器搞静态显示,就是硬件会复杂些。

再疯狂一点的,要“同时”处理多个乱七八糟的对时间要求都很高的任务,就要搞实时操作系统rtos了(卖弄了,一般是用不到啦~
离线xjl
发帖
1244
只看该作者 10楼 发表于: 2008-08-26
[quote=小比尔/5]不好意思,卖弄了。
其实c用好了比汇编简单,汇编老要研究怎么传递参数,c可以直接利用参数来传
比如说

假设有个动态显示的函数(右侧用汇编类比):
void display(unsigned char num);  // display: mov p0,a/ ret
一个扫描的函数:
unsigned char scankey();  // scankey: .../ ret
一个延时函数:
void delay();  // delay: mov r2,#xx .../ djnz ... /ret

那么你可以这样:
while(1)  // 主程序循环  main:
{
  unsigned char i,key;
  p2=0x80;  // mov p2,#80h
  for(i=4;i>0;i--)  // 显示循环  for:
  {
    display(...);  // 显示一位  mov a,.../ acall display
    key=scankey();  // 扫键  acall scankey/ push acc
    delay();  // 延时  acall delay/ pop acc
    if(key!=0) key=scankey();  // 键消抖 jz main0/ acall scankey / main0:...
    switch(key)  // ...
    {
      case up: addnum();break;  // 加1  cjne main1/ acall addnum
      case down: ...;break;  // ...  main1: cjnz main2/ acall ...
      case left: ...;break;  // ...
      case right: ...;break;  // ...
      case ...
      default: break;
    }
    p2=p2>>1;  // 字位码右移  // mov a,p2/ rl a/ mov p2,a
  } /* for */  // djnz r5, for
}  // ajmp main

整个流程和汇编其实是一样的,这个过程由你自己安排。当然,处理按键的时候,显示扫描就会受到影响。

所以如果要处理和动态显示互不影响,就要把显示放到中断去,当然也可以用移位寄存器搞静态显示,就是硬件会复杂些。

再疯狂一点的,要“同时”处理多个乱七八糟的对时间要求都很高的任务,就要搞实时操作系统rtos了(卖弄了,一般是用不到啦~ )[/quote]
谢谢详细的讲解,明白了.谢谢!!! 并不是您卖弄,是我还有很长的路要走,很多的知识要学呀
离线antforum
发帖
218
只看该作者 11楼 发表于: 2008-08-26
用c比汇编更方便