本帖最后由 keer_zu 于 2017-9-27 07:21 编辑
06年初,之前做过维修,做电子设计还是刚入行,只会protel基本操作,c语言很生硬。
当时还没做过电路板。。。。
同事介绍了21ic,就这样注册之,开始了菜鸟之旅。
在这里,我分享了我第一块电路板,得到了不少坛友的指点和夸赞。
(这个帖子二姨做调整的时候找不到了,别的地方还有:第一块板子)
(被别的站盗用了。还留下了水印)
在这里我分享了我写的第一段C代码,得到了大家的鼓励。
第一段C代码,51单片机:
这个 void text(void)可是我的处女作啊
//////////////////////////////////////////////////////////////////////////////////////////////////////
void text(void)
{
bit Flag_add; /*加一标志*/
bit Flag_sub; /*减一标志*/
unsigned char max_value; /*各时间单位的最大值*/
unsigned char min_value; /*各时间单位的最小值*/
/*if(FUN==1)
{ */ /*定义标志位*/
if(switch_work==0) /*移位键*/
{
if(Shift_on==0)
{
Shift_on=1;
buzzer();
clk_number++;
if(clk_number>6)clk_number=1;
}
}
else
Shift_on=0;
if(switch_up==0) /*加一键*/
{
if(Add_on==0)
{
Add_on=1;
buzzer();
Flag_add=1;
}
}
else
Add_on=0;
if(switch_down==0) /*减一键*/
{
if(Sub_on==0)
{
Sub_on=1;
buzzer();
Flag_sub=1;
}
}
else
Sub_on=0;
switch(clk_number)
{
case 1: max_value=99;min_value=0;break;
case 2: max_value=12;min_value=1;break;
case 3: if(clk_data[1]==1||
clk_data[1]==3||
clk_data[1]==5||
clk_data[1]==7||
clk_data[1]==8||
clk_data[1]==10||
clk_data[1]==12)
max_value=31; /*1,3,5,7,8,10,12*/
else if(
clk_data[1]==4||
clk_data[1]==6||
clk_data[1]==9||
clk_data[1]==11)
max_value=30; /*4,6,9,11*/
else if((clk_data[0]%4==0)||clk_data[0]==0)
max_value=29; /*闰年*/
else
max_value=28;
min_value=1;
break;
case 4: max_value=23;min_value=0;break;
case 5: max_value=59;min_value=0;break;
case 6: max_value=7;min_value=1;break;
}
if(Flag_add==1)
{
clk_data[clk_number-1]++;
Flag_add=0;
if(clk_data[clk_number-1]>max_value)
clk_data[clk_number-1]=min_value;
}
else if(Flag_sub==1)
{
clk_data[clk_number-1]--;
Flag_sub=0;
if(clk_data[clk_number-1]<min_value||clk_data[clk_number-1]==0xff)
clk_data[clk_number-1]=max_value;
}
if(switch_function==0)
{
if(function_on==0)
{
function_on=1;
FUN=0;
buzzer();
function_state=1;
fun0_flag=1;
set_time[0]=(clk_data[4]/10)*0x10+(clk_data[4]%10);
set_time[1]=(clk_data[3]/10)*0x10+(clk_data[3]%10);
set_time[2]=(clk_data[2]/10)*0x10+(clk_data[2]%10);
set_time[3]=(clk_data[1]/10)*0x10+(clk_data[1]%10);
set_time[4]=(clk_data[5]/10)*0x10+(clk_data[5]%10);
set_time[5]=(clk_data[0]/10)*0x10+(clk_data[0]%10);
}
}
else
{
function_on=0;
}
}
注:上面这个函数是我在51里面跑过的第一段代码,很有收藏价值,哈哈
再后来主要是写单片机代码,设计过modbus协议代码,做过菜单什么的。
也参照过坛友 @xwj 的代码,现在还保留着:
xwj优化的通用菜单程序
//呵呵,都在讨论菜单啊?那我也来优化一个! //
//大家多提意见哦:-) //
// //
//--------------------------------------------------------------------------//
// //
// (c) Copyright 2007-2008 xuwenjun //
// All Rights Reserved //
// V1.00 //
//--------------------------------------------------------------------------//
//标 题: xwj优化的通用菜单程序 //
//文件名: xwj_menu.c //
//版 本: V1.00 //
//修改人: xwj E-mail:xuwenjun[url=home.php?mod=space&uid=329077]@21cn.com[/url] //
//日 期: 07-10-25 //
//描 述: xwj优化的通用菜单程序 //
//声 明: //
// 以下代码仅免费提供给学习用途,但引用或修改后必须在文件中声明出处. //
// 如用于商业用途请与作者联系. E-mail:xuwenjun[url=home.php?mod=space&uid=329077]@21cn.com[/url] //
// 有问题请mailto xuwenjun[url=home.php?mod=space&uid=329077]@21cn.com[/url] 欢迎与我交流! //
//--------------------------------------------------------------------------//
//老版本: 无 老版本文件名: //
//创建人: xwj E-mail:xuwenjun[url=home.php?mod=space&uid=329077]@21cn.com[/url] //
//日 期: 03-11-06 //
//--------------------------------------------------------------------------//
//描 述: //
// xwj优化的通用菜单程序 //
// MCU 型号: 任意 //
// 开发环境: ANSI C任意平台 //
// 开发日期: 2007.10.25 //
// 程序编写: XWJ //
//--------------------------------------------------------------------------//
// 程序特点: //
//1、程序和数据的分离,菜单可任意定义,甚至放在RAM里 //
//2、定义好链表和菜单条目后,即可自动显示菜单、自动循环、跳转、执行, //
// 自动控制程序流向,不需任何额外的判断和switch //
//3、保留菜单路径,可原路返回(当然,也可直接跳回去啦:-) ) //
//4、可任意定义菜单层数,每层菜单可以任意组织,多一层菜单仅需增加1字节RAM //
//5、节省内存,仅需2字节+菜单层数个RAM //
//--------------------------------------------------------------------------//
#include <stdio.h>
#include “my_displays.h” //my_displays.c中包含char putchar (char)的实体
//和 液晶显示模块(点、线、填充...)
//以及printat(x,y,char*),有此足以实现任何界面显示
#define MENU_MAX_LAYER 16 //菜单链最大层数,示例只用到4层
#define MENU_NUM_OF_PAGE 4 //每页可以显示菜单数目
unsigned char Menu_tree[MENU_MAX_LAYER]; //菜单按键树,类似堆栈
unsigned char Menu_tree_ptr; //当前菜单按键树所在层数
unsigned char Menu_item_ptr; //当前菜单项在本层中位置
typedef struct
{
unsigned char code *Menu_NextTab; //本级菜单菜单链表
char code *Menu_Name; //当前菜单名称
void (*CurrentOperate)(); //当前状态应该执行的功能操作
}Menustruct;
void (*KeyFuncPtr)(); //按键功能指针
void refur_Menu(void); //刷新菜单层,就是依次打印总标题、各个条目,
void refur_Menu_item(void); //刷新本层菜单项,就是恢复原来项颜色,反显当前项
//则两个函数和界面布局有关,自己写吧
extern void ScanKey(void); //键盘扫描
void Menu_Key_Func(unsigned char NowKey); //菜单按键功能
{
switch(NowKey)
{
case KEY_UP:
if(*(KeyTab[Menu_tree][Menu_tree_ptr]].Menu_NextTab)) //Menu_NextTab[0]不为0,是菜单
// 也可以判断函数指针是否是NULL,写成下面这样:
// if(KeyTab[Menu_tree][Menu_tree_ptr]].CurrentOperate == NULL)) //Menu_NextTab[0]不为0,是菜单
{
Menu_item_ptr--; //菜单项上移
if(Menu_tree_ptr== -1) //菜单项上移到顶翻转了,修正到最后一项
Menu_item_ptr=sizeof(*(KeyTab[Menu_tree][Menu_tree_ptr]].Menu_NextTab))-1; //菜单循环
refur_Menu_item(); //刷新本层菜单项
}
else
Error_Beep(); //否则不是菜单,上下移无效,蜂鸣警告
break;
case KEY_doWN:
if(*(KeyTab[Menu_tree][Menu_tree_ptr].Menu_NextTab)) //Menu_NextTab[0]不为0,是菜单
{
Menu_item_ptr++; //菜单项下移
if(Menu_item_ptr==sizeof(*(KeyTab[Menu_tree][Menu_tree_ptr]].Menu_NextTab))-1) //菜单项下移到底
Menu_item_ptr=0; //菜单项下移到底,循环上去
refur_Menu_item(); //刷新本层菜单项
}
else
Error_Beep(); //否则不是菜单,上下移无效,蜂鸣警告
break;
case KEY_OK://KEY_OK, KEY_UP, KEY_ESC,
if(*(KeyTab[Menu_tree][Menu_tree_ptr]].Menu_NextTab)) //Menu_NextTab[0]不为0,是菜单
{
Menu_tree[Menu_tree_ptr+1]=KeyTab[Menu_tree][Menu_tree_ptr]].Menu_NextTab[Menu_item_ptr]);
//下一级菜单压进菜单树,能看懂吗?
Menu_tree_ptr++; //菜单又多了一级
refur_Menu(); //刷新菜单层,当前菜单当然是在Menu_tree[Menu_tree_ptr]中啦
}
else //不是菜单,执行当前菜单项的操作
{
KeyFuncPtr=KeyTab[Menu_tree][Menu_tree_ptr]].CurrentOperate;
(*KeyFuncPtr)(); //执行当前菜单项的操作
}
break;
case KEY_ESC:
//
if(Menu_tree_ptr) //当前菜单位置不是顶层(主界面)
{
Menu_tree_ptr--; //则返回上一层
refur_Menu(); //刷新菜单层,当前菜单当然是在Menu_tree[Menu_tree_ptr]中啦
}
else
Error_Beep(); //否则蜂鸣警告
break;
//
//case Other:
//....
} //
}
//************************************************************************
//Menu struct: //菜单示例,共4层19项
//************************************************************************
// First Bmp--------------------->(MenuID_0)
// ---+
// |View--------------------->(MenuID_1)
// +---+
// | |About Recorde-------->(MenuID_2)
// | +--------------
// | |HandSet Clock-------->(MenuID_3)
// | +--------------
// |Operation---------------->(MenuID_4)
// +---+
// |Set Position--------->(MenuID_5)
// +---+
// | |Rd Zj To Flash------->(MenuID_6)
// | +--------------
// | |Rd Zl To Ram--------->(MenuID_7)
// | +--------------
// | |Del Given Zl--------->(MenuID_8)
// | +--------------
// | |Del All Zl----------->(MenuID_9)
// | +--------------
// |Test--------------------->(MenuID_10)
// +---+
// | |Ram Test------------->(MenuID_11)
// | +--------------
// | |Flash Test----------->(MenuID_12)
// | +--------------
// |System Set--------------->(MenuID_13)
// +---+
// |Debug---------------->(MenuID_14)
// +---+
// | |PassWord--------->(MenuID_15)
// | +--------------
// | |See Picture------>(MenuID_16)
// | +--------------
// |Set Hand Clk--------->(MenuID_17)
// +--------------
//************************************************************************
//菜单链表,每项菜单一条,共19项
unsigned char code Tab_First_Bmp[]=
{1,4,0x00
};
unsigned char code Tab_View[]=
{2,3,0x00
};
unsigned char code Tab_About_Recorde[]=
{0x00
};
unsigned char code Tab_HandSet[]=
{0x00
};
unsigned char code Tab_Operation[]=
{5,10,13,14,17,0x00
};
unsigned char code Tab_Set_Position[]=
{6,7,8,9,0x00
};
unsigned char code Tab_Rd_Zj_To_Flash[]=
{0x00
};
//...
//每项菜单一条,共19项
//菜单结构,每项菜单一条,,共19项
KeyTabstruct code KeyTab[]=
{
//Menu_NextTab, Menu_Name, CurrentOperate
//本级菜单菜单链表, 当前菜单名称, 当前状态应该执行的功能操作
{Tab_First_Bmp,"First_Bmp",*First_Bmp}, //实际上菜单功能可以为NULL,由refur_Menu()统一操作;
{Tab_View,"View",*View}, //不是菜单则用实际功能函数
{Tab_About_Recorde,"About Recorde",*About_Recorde}, //非菜单
{Tab_HandSet Clock,"HandSet Clock",*HandSet_Clock}, //非菜单
{Tab_Operation,"Operation",*NULL}, //菜单
{Tab_Set_Position,"Set Position",*NULL}, //菜单
{Tab_Rd_Zj_To_Flash,"Rd Zj To Flash",*Rd_Zj_To_Flash}, //非菜单
//...
//每项菜单一条,共19项
};
//使用方法:
//1、定义好链表和菜单条目,写好每个功能函数
//2、主循环中不停的读按键,然后Menu_Key_Func();即可自动显示菜单、自动循环、跳转、执行
//比如:
void main(void)
{
Menu_tree_ptr=0; //当前菜单按键树所在层数
Menu_item_ptr=0; //当前菜单项在本层中位置
refur_Menu(); //刷新顶层菜单
refur_Menu_item(); //刷新本层菜单项
while(1)
{
ScanKey(); //键盘扫描
if(KeyOk)
Menu_Key_Func(); //有按键则执行按键功能
}
}
研究和使用过一段时间ucosII.
感谢 @ayb_ice 的耐心指教。
再后来又涉及一些电路的问题,有一段时间来得少,那段时间主要做嵌入式linux下的应用和驱动。
后来我又经常来了,而且还参与了版块的管理。
又认识了很多新朋友,包括 @yyy71cj 等。
21ic伴随了我职业的成长,给我很多帮助,我也非常乐意和大家分享。实在是不可或缺的精神家园。
感谢21ic,感谢各位坛友。
|
|