哈哈!我的第一个C程序和第二个和第……
爱非神话2009/07/07软件综合 IP:广东
不懂C,学AVR太艰难了,于是周末去购书中心买了本C语言入门,狂啃了2天,今晚熬到现在总算用自己的思路(当然里面还是有许多书上例题的影子的[s:98])编出了自己的第一个程序并上板调试通过,哈哈,发帖纪念下……[s:232]
简单的功能,两位数码管循环显示从00~99……不容易啊,尝试了N种方法,N次失败啊……
总算成功了![s:92] C路漫长,加油!

******************我的第一个C程序:双数码管循环显示0~99******************
#include <iom48v.h>
#include <macros.h>
#include "delay.h"        /*拿来主义的延时函数*/  
#include "led_dis.h"      /*LED数码管断码表*/

#define Led_a 0b11111110      /*定义十位数码管点亮输出脚*/  
#define Led_b 0b11111101     /*定义个位数码管点亮输出脚*/  
#define Led_M 0b11111111    /*定义关闭所有数码管*/  

void main (void)
{
    unsigned char Counter=10;
    int a,b,c;
    
    DDRC=0xFF;
    DDRB=0xFF;
    DDRD=0xFF;
    PORTC=0xFF;
    PORTB=0xFF;
    PORTD=0xFF;
    
    haha: ;
    a=0;
    b=0;
    c=0;
    
    for (;c<10000;Counter=c/100)     /*这两个参数决定了计数器的递增频率与总循环数*/
    {
        a=Counter/10;
        PORTD=DisTab[a];
        PORTB=Led_a;        /*点亮十位数码管*/
        Delay_ms(3);
        b=Counter%10;
        PORTD=DisTab[b];
        PORTB=Led_b;        /*点亮个位数码管*/
        Delay_ms(3);
        PORTB=Led_M;                     /*关闭所有的数码管*/
        Delay_ms(10);
        c++;
    }
    
    goto haha;
}
来自:计算机科学 / 软件综合
17
已屏蔽 原因:{{ notice.reason }}已屏蔽
{{notice.noticeContent}}
~~空空如也
爱非神话 作者
15年8个月前 IP:未同步
120141
也许这样实现两位数显是不科学的……不过以目前的学习进度只能想到这种方法了…… [s:245]
引用
评论
加载评论中,请稍候...
200字以内,仅用于支线交流,主线讨论请采用回复功能。
折叠评论
jrcsh
15年8个月前 IP:未同步
120146
拿来主义  不会是哪本书吧   是很合抄来用  我也有本 不过是在新华书店买的

C的列子 我还有些~~~~~  


/*                                                                             *
*                 数码管显示秒表, 分辨率0.01s                                     *
*                 K1=P1.4---控制按钮                                           *
*                       第一次按下时, 启动开始计时                             *
*                       第二次按下时, 停止                                     *
*                       第三次按下时, 归零                                     *
*                                                                              *
*    秒单位,寄存器与数码管对应关系:                                            *
*                                                                              *
* --- 秒单位 ---------- 数码管端口 ---- 缓冲区 --------- 计时BCD码值寄存器     *
*     十万位               P20        dis_buf[7]          sec_bcd[7]           *
*     万位                 P21        dis_buf[6]          sec_bcd[6]           *
*     千位                 P22        dis_buf[5]          sec_bcd[5]           *
*     百位                 P23        dis_buf[4]          sec_bcd[4]           *
*     十位                 P24        dis_buf[3]          sec_bcd[3]           *
*     个位(1.s)            P25        dis_buf[2]          sec_bcd[2]           *
*     十分位(0.1s)         P26        dis_buf[1]          sec_bcd[1]           *
*     百分位(0.01s)        P27        dis_buf[0]          sec_bcd[0]           *
*                                                                              *
********************************************************************************
*/

#include <reg51.h>
#include <intrins.h>

unsigned char data dis_digit;
unsigned char key_s, key_v;

unsigned char code dis_code[11]={0xc0,0xf9,0xa4,0xb0,    // 0, 1, 2, 3
                0x99,0x92,0x82,0xf8,0x80,0x90, 0xff};// 4, 5, 6, 7, 8, 9, off
unsigned char dis_buf[8];        // 显示缓冲区
unsigned char sec_bcd[8];         // 秒计数值, BCD码
unsigned char dis_index;        //
unsigned char key_times;        // K1 按下次数                //

void clr_time();    
void update_disbuf();
bit    scan_key();
void proc_key();
void delayms(unsigned char ms);

sbit    K1 = P3^7;


void main(void)
{
    P0 = 0xff;
    P2 = 0xff;
    TMOD = 0x11;        // 定时器0, 1工作模式1, 16位定时方式
    TH1 = 0xdc;
    TL1 = 0;

    TH0 = 0xFC;
    TL0 = 0x17;
    
    clr_time();            //
                              
    dis_digit = 0x7f;        // 初始显示P20口数码管
    dis_index = 0;            //
    
    key_times = 0;
    key_v = 0x01;
    
    IE = 0x8a;                // 使能timer0, timer1中断
    
    TR0 = 1;
    TR1 = 0;
    while(1)
    {
        if(scan_key())
        {
            delayms(10);
            if(scan_key())
            {
                key_v = key_s;
                proc_key();
            }
        }
        
    }
}

void clr_time()
{
    sec_bcd[0] = 0x0;
    sec_bcd[1] = 0x0;
    sec_bcd[2] = 0x0;
    sec_bcd[3] = 0x0;
    sec_bcd[4] = 0x0;
    sec_bcd[5] = 0x0;
    sec_bcd[6] = 0x0;
    sec_bcd[7] = 0x0;  
    
    update_disbuf();
    
}

bit scan_key()
{
    key_s = 0x00;
    key_s |= K1;
    return(key_s ^ key_v);    
}

void proc_key()
{
    if((key_v & 0x01) == 0)
    {
        key_times++;
        if(key_times == 1)
        {
            TR1 = 1;
        }
        else if(key_times == 2)
        {    
            TR1 = 0;
        }
        else
        {
            clr_time();
            key_times = 0;
        }
        
    }
}

void timer0() interrupt 1
// 定时器0中断服务程序, 用于数码管的动态扫描
// dis_index --- 显示索引, 用于标识当前显示的数码管和缓冲区的偏移量
// dis_digit --- 位选通值, 传送到P2口用于选通当前数码管的数值, 如等于0xfe时,
//                选通P2.0口数码管
// dis_buf   --- 显于缓冲区基地址    
{
    TH0 = 0xFC;
    TL0 = 0x17;
    
    P2 = 0xff;                            // 先关闭所有数码管
    P0 = dis_buf[dis_index];            // 显示代码传送到P0口
    P2 = dis_digit;                        //

    dis_digit = _cror_(dis_digit,1);    // 位选通值右移(P20<-P27), 下次中断时选通下一位数码管
    dis_index++;                        //
                    
    dis_index &= 0x07;            // 8个数码管全部扫描完一遍之后,再回到第一个开始下一次扫描
}

void timer1() interrupt 3
//
{    
    unsigned char i;
    TH1 |= 0xdc;
    for(i = 0; i < 8; i++)
    {
        sec_bcd[i]++;            // 低位加1
        if(sec_bcd[i] < 10)        // 如果低位满10则向高位进1
            break;            // 低位未满10
        sec_bcd[i] = 0;            // 低位满10清0
    }
    update_disbuf();            // 更新显示缓冲区
}

void update_disbuf()
// 更新显示缓冲区
{
    dis_buf[0] = dis_code[sec_bcd[0]];
    dis_buf[1] = dis_code[sec_bcd[1]];
    dis_buf[2] = dis_code[sec_bcd[2]] & 0x7f;    // 加上小数点
    dis_buf[3] = dis_code[sec_bcd[3]];
    dis_buf[4] = dis_code[sec_bcd[4]];
    dis_buf[5] = dis_code[sec_bcd[5]];
    dis_buf[6] = dis_code[sec_bcd[6]];
    dis_buf[7] = dis_code[sec_bcd[7]];
}

void delayms(unsigned char ms)    
// 延时子程序
{                        
    unsigned char i;
    while(ms--)
    {
        for(i = 0; i < 120; i++);
    }
}




























++++++++++++++++++++++++++++++++++++++++++++++++++=另一个





#include <reg51.h>
#include <intrins.h>

unsigned char data dis_digit;
unsigned char code dis_code[11]={0xc0,0xf9,0xa4,0xb0,    // 0, 1, 2, 3
                0x99,0x92,0x82,0xf8,0x80,0x90, 0xff};// 4, 5, 6, 7, 8, 9, off
unsigned char data dis_buf[8];
unsigned char data dis_index;

void main()
{
    P0 = 0xff;
    P2 = 0xff;
    TMOD = 0x01;
    TH0 = 0xFC;
    TL0 = 0x17;
    IE = 0x82;

    dis_buf[0] = dis_code[0x1];
    dis_buf[1] = dis_code[0x2];
    dis_buf[2] = dis_code[0x3];
    dis_buf[3] = dis_code[0x4];
    dis_buf[4] = dis_code[0x5];
    dis_buf[5] = dis_code[0x6];
    dis_buf[6] = dis_code[0x7];
    dis_buf[7] = dis_code[0x8];
    
    dis_digit = 0xfe;
    dis_index = 0;
    
    TR0 = 1;
    while(1);

}

void timer0() interrupt 1
// 定时器0中断服务程序, 用于数码管的动态扫描
// dis_index --- 显示索引, 用于标识当前显示的数码管和缓冲区的偏移量
// dis_digit --- 位选通值, 传送到P2口用于选通当前数码管的数值, 如等于0xfe时,
//                选通P2.0口数码管
// dis_buf   --- 显于缓冲区基地址    
{
    TH0 = 0xFC;
    TL0 = 0x17;
    
    P2 = 0xff;                            // 先关闭所有数码管
    P0 = dis_buf[dis_index];            // 显示代码传送到P0口
    P2 = dis_digit;                        //

    dis_digit = _crol_(dis_digit,1);    // 位选通值左移, 下次中断时选通下一位数码管
    dis_index++;                        //
                    
    dis_index &= 0x07;            // 8个数码管全部扫描完一遍之后,再回到第一个开始下一次扫描
}
引用
评论
加载评论中,请稍候...
200字以内,仅用于支线交流,主线讨论请采用回复功能。
折叠评论
jrcsh
15年8个月前 IP:未同步
120148
我还是停滞在 C51 上   AVR  的板不少银子阿  ARM 到是多一些路由器上得到样板~~~~可以玩可惜还不会玩


我还是先吧 51学个 半桶水先
引用
评论
加载评论中,请稍候...
200字以内,仅用于支线交流,主线讨论请采用回复功能。
折叠评论
93°
15年8个月前 IP:未同步
120181
C最萌啊。。。
引用
评论
加载评论中,请稍候...
200字以内,仅用于支线交流,主线讨论请采用回复功能。
折叠评论
爱非神话作者
15年8个月前 IP:未同步
120207
LS~

引用第2楼jrcsh于2009-07-07 03:10发表的  :
拿来主义  不会是哪本书吧   是很合抄来用  我也有本 不过是在新华书店买的
.......


购书中心==新华书店

引用第4楼93°于2009-07-07 08:53发表的  :
C最萌啊。。。


0100100110001110010……最萌

[s:124]
引用
评论
加载评论中,请稍候...
200字以内,仅用于支线交流,主线讨论请采用回复功能。
折叠评论
jrcsh
15年8个月前 IP:未同步
120211
引用第6楼爱非神话于2009-07-07 09:58发表的  :
LS~
购书中心==新华书店
.......



购书中心 指点的是 体育中心旁边哪个

新华书店指的是北京路哪个
引用
评论
加载评论中,请稍候...
200字以内,仅用于支线交流,主线讨论请采用回复功能。
折叠评论
爱非神话作者
15年8个月前 IP:未同步
120220
引用第7楼jrcsh于2009-07-07 10:16发表的  :



购书中心 指点的是 体育中心旁边哪个

.......


呃……原来是这样子,我一直以为是一个……汗~
那边规模怎样?比起购书中心?反正我每次去购书中心都是直奔四楼的……其它楼层一概无视。
引用
评论
加载评论中,请稍候...
200字以内,仅用于支线交流,主线讨论请采用回复功能。
折叠评论
rc5
15年8个月前 IP:未同步
120448
这几个写的不象C的文风
1. C里变量通常是全小写或大小写混合,只有宏才用全大写。
2. 循环变量应该在for循环中初始化和增量,而不是在for之前和{}之内。
3. 没有绝对必要不要用goto语句
4. 应该写成if(!P) 而不是if(p==0)
+6
科创币
爱非神话
2009-07-07
谢谢指教!
引用
评论
加载评论中,请稍候...
200字以内,仅用于支线交流,主线讨论请采用回复功能。
折叠评论
jrcsh
15年8个月前 IP:未同步
120657
引用第8楼爱非神话于2009-07-07 10:55发表的  :


呃……原来是这样子,我一直以为是一个……汗~
那边规模怎样?比起购书中心?反正我每次去购书中心都是直奔四楼的……其它楼层一概无视。


购书中心  的情况~~~我发这贴了

北京路哪家 唯一的一本单片机书就是  "拿来主意"  我也买回来了
引用
评论
加载评论中,请稍候...
200字以内,仅用于支线交流,主线讨论请采用回复功能。
折叠评论
phpskycn
15年8个月前 IP:未同步
120664
购书中心?莫非是杭州庆春路那家?
引用
评论
加载评论中,请稍候...
200字以内,仅用于支线交流,主线讨论请采用回复功能。
折叠评论
爱非神话作者
15年8个月前 IP:未同步
120811
引用第11楼jrcsh于2009-07-07 20:46发表的  :


购书中心  的情况~~~我发这贴了

北京路哪家 唯一的一本单片机书就是  "拿来主意"  我也买回来了


我的是《深入浅出AVR单片机》,然后觉得学起来有点困难,所以又去买了本《零基础学C语言》。

引用第12楼phpskycn于2009-07-07 20:52发表的  :
购书中心?莫非是杭州庆春路那家?


广州的……
引用
评论
加载评论中,请稍候...
200字以内,仅用于支线交流,主线讨论请采用回复功能。
折叠评论
爱非神话作者
15年8个月前 IP:未同步
120813
引用第10楼rc5于2009-07-07 16:22发表的  :
这几个写的不象C的文风

2. 循环变量应该在for循环中初始化和增量,而不是在for之前和{}之内。
3. 没有绝对必要不要用goto语句
4. 应该写成if(!P) 而不是if(p==0)



谢谢指教!
2.呃,我试试看……
3.我试试套个while循环
引用
评论
加载评论中,请稍候...
200字以内,仅用于支线交流,主线讨论请采用回复功能。
折叠评论
phpskycn
15年8个月前 IP:未同步
120829
还以为找到杭州的了
引用
评论
加载评论中,请稍候...
200字以内,仅用于支线交流,主线讨论请采用回复功能。
折叠评论
爱非神话作者
15年8个月前 IP:未同步
120854
*****************修改后的代码,感谢RC5的指点,已经简洁多了******************

#include <iom48v.h>
#include <macros.h>
#include "delay.h"        /*拿来主义的延时函数*/  
#include "led_dis.h"      /*LED数码管断码表*/

#define Led_a 0b11111110
#define Led_b 0b11111101
#define Led_M 0b11111111

void main (void)
{
    DDRC=0xFF;
    DDRB=0xFF;
    DDRD=0xFF;
    PORTC=0xFF;
    PORTB=0xFF;
    PORTD=0xFF;
    while(1)
    {
    unsigned char Counter;
    int a=0,b=0,c=0;
    
    for (Counter=10;c<10000;Counter=c++/100)         /*这两个参数决定了计数器的递增频率与总循环数*/
    {
        a=Counter/10;
        PORTD=DisTab[a];
        PORTB=Led_a;                     /*点亮十位数码管*/
        Delay_ms(5);
        b=Counter%10;
        PORTD=DisTab[b];
        PORTB=Led_b;                     /*点亮个位数码管*/
        Delay_ms(5);
        PORTB=Led_M;                    /*关闭所有的数码管*/
        }
    }        
}

************************分割线*********************************

有个问题,就是根据您的建议,我想将循环变量  Counter ,a,b,c 放进初始化表达式中却总是失败,但只放Counter就没问题,是否for函数的初始化表达式只允许放一个变量呢?不解……试了好几次了。
引用
评论
加载评论中,请稍候...
200字以内,仅用于支线交流,主线讨论请采用回复功能。
折叠评论
phpskycn
15年8个月前 IP:未同步
120882
for应该只能放进一个
C++中精典的…
for(i=0,i<100,i++){
......
}
Google一下:“for,初始化列表”
引用
评论
加载评论中,请稍候...
200字以内,仅用于支线交流,主线讨论请采用回复功能。
折叠评论
phpskycn
15年8个月前 IP:未同步
120883
如果把for当作函数的话……
那么其参数固定只有3个
应该只能是一个变量的
(C里还有没函数重载这一说?)
引用
评论
加载评论中,请稍候...
200字以内,仅用于支线交流,主线讨论请采用回复功能。
折叠评论
爱非神话作者
15年8个月前 IP:未同步
120917
引用第15楼phpskycn于2009-07-08 01:24发表的  :
for应该只能放进一个
C++中精典的…
for(i=0,i<100,i++){
......
}
.......


C++没了解过,怎么是用逗号隔开的?

嘿,又花了几个小时时间,终于写出了我的第二个C程序:四数码管循环显示0~999,一开始以为很简单,就在原来的双数码管显示代码基础上小作修改,结果除了个位其它的怎么都是显示乱码,要么干脆几位不显示,想了好久没找到原因,后来尝试用“程序思维”一步步跟下去,终于发现了问题所在,一位数显示与两位数显示没有太大分别,可上了三位数就得区分了,关键在于区分“几位数”以及“取其位值”,虽然中间绕了很远,但,最终还是成功了,兴奋N久!
[s:232]
***********************我的第二个C程序:四数码管循环显示0~999*******************************
#include <iom48v.h>
#include <macros.h>
#include "delay.h"  
#include "led_dis.h"

#define Led_a 0b11111110
#define Led_b 0b11111101
#define Led_c 0b11111011
#define Led_d 0b11110111
#define Led_off 0b11111111

void main (void)
{
    DDRC=0xFF;
    DDRB=0xFF;
    DDRD=0xFF;
    PORTC=0xFF;
    PORTB=0xFF;
    PORTD=0xFF;
    while(1)
    {
    int a=0,b=0,c=0,d=0,e=0,Counter;
    
    for (Counter=0;e<10000;Counter=e++/2)     /*这两个参数决定了计数器的递增频率与总循环数*/
    {
        if(Counter<=999&&Counter>99)    /*三位数情况*/
        {
        d=Counter%10;
        c=Counter/10%10;
        b=Counter/100;
        }
        else if(Counter<=9999&&Counter>999)    /*四位数情况*/
        {
        d=Counter%10;
        c=Counter/10%100%10;
        b=Counter/100%10;
        a=Counter/1000;
        }
        else             /*一或两位数情况*/
        {
        d=Counter%10;
        c=Counter/10;
        }
                
        PORTD=DisTab[a];
        PORTC=Led_a;            /*点亮千位数码管*/
        Delay_ms(5);
        PORTD=DisTab[b];
        PORTC=Led_b;        /*点亮百位数码管*/
        Delay_ms(5);
        PORTD=DisTab[c];
        PORTC=Led_c;        /*点亮十位数码管*/
        Delay_ms(5);
        PORTD=DisTab[d];
        PORTC=Led_d;        /*点亮个位数码管*/
        Delay_ms(5);
        PORTC=Led_off;    /*关闭所有的数码管*/
        }
    }        
}
引用
评论
加载评论中,请稍候...
200字以内,仅用于支线交流,主线讨论请采用回复功能。
折叠评论

想参与大家的讨论?现在就 登录 或者 注册

所属专业
上级专业
同级专业
爱非神话
学者 笔友
文章
71
回复
981
学术分
11
2008/03/23注册,7年0个月前活动
暂无简介
主体类型:个人
所属领域:无
认证方式:邮箱
IP归属地:未同步
插入公式
评论控制
加载中...
文号:{{pid}}
投诉或举报
加载中...
{{tip}}
请选择违规类型:
{{reason.type}}

空空如也

加载中...
详情
详情
推送到专栏从专栏移除
设为匿名取消匿名
查看作者
回复
只看作者
加入收藏取消收藏
收藏
取消收藏
折叠回复
置顶取消置顶
评学术分
鼓励
设为精选取消精选
管理提醒
编辑
通过审核
评论控制
退修或删除
历史版本
违规记录
投诉或举报
加入黑名单移除黑名单
查看IP
{{format('YYYY/MM/DD HH:mm:ss', toc)}}