‘壹’ 单片机设计
首先要清楚你要做一个什么样的产品,这个产品包含哪些功能,要采集哪些信号?要控制哪些设备?要走哪些通讯协议?通讯协议走什么接口?是不是要显示界面?是不是要声光提示?是不是要低功耗?清楚了这些需求以后就可以选型了。
比如说我要做一个单片机密码锁,要求:
1. 有4位数码管显示;
2. 控制一个继电器;
3. 控制一个蜂鸣器;
4. 控制五个LED灯;
5. 两个按键输入;
2 芯片选型
根据你的需求来确定所选芯片型号。如第一部分的功能需求,这5个需求都只需要用到单片机的IO口,没有用到片上资源,所以只要IO口够用就可以了。
1. 4位数码管:为了方便大家学习,这里选用74HC595来驱动,该芯片与单片机相连只需要3个IO口;
2. 控制一个继电器;这个地方主要考虑线圈电压,单片机是5V供电,所以选用5V的继电器,占用1个IO口;
3. 控制蜂鸣器:选用有源蜂鸣器,即只要给电蜂鸣器就发声,占用1个IO口;
4. 控制5个LED灯:采用灌电流的方式,占用5个IO口;
5. 两个按键输入:采用上拉电阻,按下低电平实现,占用2个IO口;
总共用了3+1+1+5+2=12个IO口;为了方便初学者,那我们就选用STC的51单片机来完成这个设计吧,所选型号为STC89C51,封装形式为DIP40,相信大家在大学里学单片机的时候老师都是用这一款教的吧。
3 硬件原理设计
芯片选型完毕之后,又有了设计思路,那就赶快把电路图画出来吧。画电路图用什么软件呢?这样的EDA工具很多,像Protel99se、DXP、Altium Designer 等,这些都是软件都是一家出的,还有Cadence、PowerPcb等。本人用的是AD09。原理图设计的内容是什么呢?设计的内容包括单片机的最小系统、还有扩展出来的功能。
4 硬件PCB设计
当原理图画完,并且检查没有错误后,就开始画PCB吧,什么是PCB?PCB就是电路板,什么是电路板,就像下图这样的:
50171510883016
这是焊接之前的电路板,PCB文件设计好后,发给厂家去打样制版,做回来的就是这样的电路板。上图中的电路板用的都是直插元件。什么是直插元件,什么是贴片元件?这就设计到元器件的封装问题了。
如果大家感兴趣,我明后天把画pcb板的过程推送给大家。
5 样板焊接
什么是样板焊接?就是把电子元器件焊接在pcb板上。如果封装简单、样板数量少那完全可以自己动手焊接了,顺便也锻炼一下自己的焊接水平,对于一个搞电的人而言,一般都是从焊电路板过来的。如果搞电但不会焊接,别人会笑话你的。
6 调试程序
程序该怎么写?用什么工具写?不同的单片机有不同的编程环境,比如PIC单片机使用MPLAB编程环境,MSP430单片机使用IAR Embedded Workbench编程环境,DSP使用CCS编程环境。这里重点介绍的编程环境是Keil,Keil是目前所有编程环境中最好用的,也是支持芯片最多的,可以说Keil是目前最主流的编程环境,本人使用的是Keil的编程环境,Keil的C51版本和MDK版本都在用。
7 程序烧录
程序烧录的意思就是把写好的程序下载到单片机里,这样单片机才会按照用户编写的程序来执行命名、实现功能。程序要怎么样才能烧写到单片机中去呢?每种单片机都有各自的程序烧录接口。
‘贰’ 51单片机接入以太网的几种方案
1、MAC+PHY方案
所谓的TCP/IP协议栈是一系列网络协议的统称,不仅包括我们熟知的TCP协议和IP协议。
还有网络层的ICMP(Internet控制报文)协议、IGMP(Internet组管理)协议、ARP(地址解析)协议,传输层的UDP(用户数据包)协议,应用层的HTTP(超文本传输)协议、DNS(域名解析)协议、FTP(文件传送)协议、SMTP(简单邮件管理)协议等等。
传统的以太网接入方案由MCU+MAC+PHY再加入网络接口实现以太网的物理连接,通过在主控芯片中植入TCP/IP协议代码实现通信及上层应用。
应用这种软件TCP/IP协议栈方式实现的比较成熟方案有ENC28J60,CS8900A,DM9000,当然也有像STM32F107这类(内部自带MAC)+PHY等方案。
2、硬件协议栈芯片方案
由MCU+硬件协议栈芯片(内含MAC和PHY)直接加网络接口,便可方便的实现单片机联网,所有的处理TCP/IP协议的工作都是通过这位MCU的“小秘书”——硬件协议栈芯片来完成。
以太网芯片的内核由传输层的TCP、UDP、ICMP、IGMP等协议、网络层的IP、ARP、PPPoE等协议以及链路层的MAC构成,再加上物理层的PHY和外围的寄存器、内存、SPI接口组成了这一整套硬件化的以太网解决方案。
这套硬件TCP/IP协议栈代替了以往的MCU来处理这些中断请求,即MCU只需要处理面向用户的应用层数据即可,传输层、网络层、链路层及物理层全部由外围WIZnet的芯片完成。
这套方案从硬件开销和软件开发两个方面来简化前面所述的五层网络模型,简化产品开发方案。这样一来,工程师们就不必再面对繁琐的通信协议代码,只需要了解简单的寄存器功能以及Socket编程便能完成产品开发工作的的网络功能开发部分。
(2)单片机方案扩展阅读
以太网协议:
一个标准的以太网物理传输帧由七部分组成。
PR SD DA SA TYPE DATA FCS
同步位 分隔位 目的地址 源地址 类型字段 数据段 帧校验序列 7 1 6 6 2 46~1500 4
除了数据段的长度不定外,其他部分的长度固定不变。数据段为46~1500字节。以太网规定整个传输包的最大长度不能超过1514字节(14字节为DA、SA、TYPE),最小不能小于60字节。
除去DA、SA、TYPE14字节,还必须传输46字节的数据,当数据段的数据不足46字节时需填充,填充字符的个数不包括在长度字段里;超过1500字节时,需拆成多个帧传送。
事实上,发送数据时,PR、SD、FCS及填充字段这几个数据段由以太网控制器自动产生;而接收数据时,PR、SD被跳过,控制器一旦检测到有效的前序字段(即PR、SD),就认为接收数据开始。
‘叁’ 单片机 求 方案
这是一个利用温感DB18B20做的温控系统!程序跟电路如下:系统描述:在LCD1602上实时显示时钟,温度,湿度,系统运行时间。利用ds18b20
检测当前温度,通过和设定参数的比较,给ISD1420发出报警脉冲,通过
功率放大器LM386 驱动喇叭报警。
*************************************************************************/#include<reg51.h>
#include<intrins.h>
#include <absacc.h>
#define uchar unsigned char
#define uint unsigned int#define BUSY 0x80 //lcd忙检测标志
#define DATAPORT P0 //定义P0口为LCD通讯端口
#define PLAYE_ADDR XBYTE[0XBFFF] //语音报警地址sbit RED_ALARM=P1^0; //红色指示灯
sbit WRITE_ALARM=P1^1; //白色指示灯
sbit GREEN_ALARM=P1^2; //绿色指示灯
sbit P1_4=P1^4; //时钟调整
sbit P1_5=P1^5; //时钟加
sbit P1_6=P1^6; //时钟减sbit DQ = P1^7; //定义ds18b20通信端口
sbit LCM_RS=P2^0; //数据/命令端
sbit LCM_RW=P2^1; //读/写选择端
sbit LCM_EN=P2^2; //LCD使能信号
sbit ad_busy=P3^2; //adc中断方式接口
sbit RECLED_EOC=P3^5; //ISD1420放音结束查询标志
sbit OUT=P3^7;uchar ad_data; //ad采样值存储
uchar seconde=0; //定义并初始化时钟变量
uchar minite=0;
uchar hour=12;
uchar mstcnt=0;
uchar temp1,temp2,temp; //温度显示变量
uchar t,set;
uchar T;
bit ON_OFF;
bit outflag;uchar code str0[]={"--- : : ---OF"};
uchar code str1[]={"SET: C SA: . C"};void delay_LCM(uint); //LCD延时子程序
void initLCM( void); //LCD初始化子程序
void lcd_wait(void); //LCD检测忙子程序
void WriteCommandLCM(uchar WCLCM,uchar BusyC); //写指令到ICM子函数
void WriteDataLCM(uchar WDLCM); //写数据到LCM子函数
void DisplayOneChar(uchar X,uchar Y,uchar DData); //显示指定坐标的一个字符子函数
void DisplayListChar(uchar X,uchar Y,uchar code *DData); //显示指定坐标的一串字符子函数
void init_timer0(void); //定时器初始化
void displayfun1(void);
void displayfun2(void);
void displayfun3(void);
void displayfun4(void);
void keyscan(void ); //键盘扫描子程序
void set_adj(void);
void inc_key(void);
void dec_key(void);
void delay_18B20(unsigned int i);
void Init_DS18B20(void) ;
uchar ReadOneChar(void);
void WriteOneChar(unsigned char dat);
void ReadTemperature(void);
void ad0809(void);
void playalarm(void);
/*********延时K*1ms,12.000mhz**********/void delay_LCM(uint k)
{
uint i,j;
for(i=0;i<k;i++)
{
for(j=0;j<60;j++)
{;}
}
}
/**********写指令到ICM子函数************/void WriteCommandLCM(uchar WCLCM,uchar BusyC)
{
if(BusyC)lcd_wait();
DATAPORT=WCLCM;
LCM_RS=0; // 选中指令寄存器
LCM_RW=0; // 写模式
LCM_EN=1;
_nop_();
_nop_();
_nop_();
LCM_EN=0;
}/**********写数据到LCM子函数************/void WriteDataLCM(uchar WDLCM)
{
lcd_wait( ); //检测忙信号
DATAPORT=WDLCM;
LCM_RS=1; // 选中数据寄存器
LCM_RW=0; // 写模式
LCM_EN=1;
_nop_();
_nop_();
_nop_();
LCM_EN=0;
}/***********lcm内部等待函数*************/void lcd_wait(void)
{
DATAPORT=0xff;
LCM_EN=1;
LCM_RS=0;
LCM_RW=1;
_nop_();
while(DATAPORT&BUSY)
{ LCM_EN=0;
_nop_();
_nop_();
LCM_EN=1;
_nop_();
_nop_();
}
LCM_EN=0;
}/**********LCM初始化子函数***********/void initLCM( )
{
DATAPORT=0;
delay_LCM(15);
WriteCommandLCM(0x38,0); //三次显示模式设置,不检测忙信号
delay_LCM(5);
WriteCommandLCM(0x38,0);
delay_LCM(5);
WriteCommandLCM(0x38,0);
delay_LCM(5); WriteCommandLCM(0x38,1); //8bit数据传送,2行显示,5*7字型,检测忙信号
WriteCommandLCM(0x08,1); //关闭显示,检测忙信号
WriteCommandLCM(0x01,1); //清屏,检测忙信号
WriteCommandLCM(0x06,1); //显示光标右移设置,检测忙信号
WriteCommandLCM(0x0c,1); //显示屏打开,光标不显示,不闪烁,检测忙信号
}/****************显示指定坐标的一个字符子函数*************/void DisplayOneChar(uchar X,uchar Y,uchar DData)
{
Y&=1;
X&=15;
if(Y)X|=0x40; //若y为1(显示第二行),地址码+0X40
X|=0x80; //指令码为地址码+0X80
WriteCommandLCM(X,0);
WriteDataLCM(DData);
}/***********显示指定坐标的一串字符子函数***********/void DisplayListChar(uchar X,uchar Y,uchar code *DData)
{
uchar ListLength=0;
Y&=0x01;
X&=0x0f;
while(X<16)
{
DisplayOneChar(X,Y,DData[ListLength]);
ListLength++;
X++;
}
}/***********ds18b20延迟子函数(晶振12MHz )*******/ void delay_18B20(unsigned int i)
{
while(i--);
}/**********ds18b20初始化函数**********************/void Init_DS18B20(void)
{
unsigned char x=0;
DQ = 1; //DQ复位
delay_18B20(8); //稍做延时
DQ = 0; //单片机将DQ拉低
delay_18B20(80); //精确延时 大于 480us
DQ = 1; //拉高总线
delay_18B20(14);
x=DQ; //稍做延时后 如果x=0则初始化成功 x=1则初始化失败
delay_18B20(20);
}/***********ds18b20读一个字节**************/ unsigned char ReadOneChar(void)
{
uchar i=0;
uchar dat = 0;
for (i=8;i>0;i--)
{
DQ = 0; // 给脉冲信号
dat>>=1;
DQ = 1; // 给脉冲信号
if(DQ)
dat|=0x80;
delay_18B20(4);
}
return(dat);
}/*************ds18b20写一个字节****************/ void WriteOneChar(uchar dat)
{
unsigned char i=0;
for (i=8; i>0; i--)
{
DQ = 0;
DQ = dat&0x01;
delay_18B20(5);
DQ = 1;
dat>>=1;
}
}/**************读取ds18b20当前温度************/void ReadTemperature(void)
{
unsigned char a=0;
unsigned char b=0;
unsigned char t=0; Init_DS18B20();
WriteOneChar(0xCC); // 跳过读序号列号的操作
WriteOneChar(0x44); // 启动温度转换 delay_18B20(100); // this message is wery important Init_DS18B20();
WriteOneChar(0xCC); //跳过读序号列号的操作
WriteOneChar(0xBE); //读取温度寄存器等(共可读9个寄存器) 前两个就是温度 delay_18B20(100); a=ReadOneChar(); //读取温度值低位
b=ReadOneChar(); //读取温度值高位
temp1=b<<4;
temp1+=(a&0xf0)>>4;
temp2=a&0x0f; temp=((b*256+a)>>4); //当前采集温度值除16得实际温度值
}/***************液晶显示子函数1正常显示*****************/void displayfun1(void)
{
WriteCommandLCM(0x0c,1); //显示屏打开,光标不显示,不闪烁,检测忙信号
DisplayListChar(0,0,str0);
DisplayListChar(0,1,str1);
DisplayOneChar(3,0,hour/10+0x30); //液晶上显示小时
DisplayOneChar(4,0,hour%10+0x30); DisplayOneChar(6,0,minite/10+0x30); //液晶上显示分
DisplayOneChar(7,0,minite%10+0x30);
DisplayOneChar(9,0,seconde/10+0x30); //液晶上显示秒
DisplayOneChar(10,0,seconde%10+0x30); DisplayOneChar(4,1,T/10+0x30); //液晶上显示设定的温度
DisplayOneChar(5,1,T%10+0x30);
DisplayOneChar(11,1,temp1/10+0x30); //液晶上显示测得的温度
DisplayOneChar(12,1,temp1%10+0x30);
DisplayOneChar(14,1,temp2/10+0x30); if(ON_OFF==0) //若温控标志为0
{
DisplayOneChar(14,0,0x4f); // 液晶上显示不控温的标志
DisplayOneChar(15,0,0x46);
}
else
{
DisplayOneChar(14,0,0x4f); // 液晶上显示控温的标志
DisplayOneChar(15,0,0x4e);
if(outflag==1)
DisplayOneChar(0,0,0x7c);
else
DisplayOneChar(0,0,0xef);
}
}
/************液晶显示子函数2***************/void displayfun2(void)
{
WriteCommandLCM(0x0c,1); //显示屏打开,光标不显示,不闪烁,检测忙信号
DisplayListChar(0,0,str0);
DisplayListChar(0,1,str1);
DisplayOneChar(6,0,minite/10+0x30);
DisplayOneChar(7,0,minite%10+0x30);
DisplayOneChar(9,0,seconde/10+0x30);
DisplayOneChar(10,0,seconde%10+0x30); DisplayOneChar(4,1,T/10+0x30);
DisplayOneChar(5,1,T%10+0x30);
DisplayOneChar(11,1,temp1/10+0x30);
DisplayOneChar(12,1,temp1%10+0x30);
DisplayOneChar(14,1,temp2/10+0x30); WriteCommandLCM(0x0f,1); //显示屏打开,光标显示,闪烁,检测忙信号
DisplayOneChar(3,0,hour/10+0x30);
DisplayOneChar(4,0,hour%10+0x30);
}/**************液晶显示子函数3*****************/void displayfun3(void)
{
WriteCommandLCM(0x0c,1); //显示屏打开,光标不显示,不闪烁,检测忙信号
DisplayListChar(0,0,str0);
DisplayListChar(0,1,str1);
DisplayOneChar(3,0,hour/10+0x30);
DisplayOneChar(4,0,hour%10+0x30); DisplayOneChar(9,0,seconde/10+0x30);
DisplayOneChar(10,0,seconde%10+0x30); DisplayOneChar(4,1,T/10+0x30);
DisplayOneChar(5,1,T%10+0x30); DisplayOneChar(11,1,temp1/10+0x30);
DisplayOneChar(12,1,temp1%10+0x30);
DisplayOneChar(14,1,temp2/10+0x30);
WriteCommandLCM(0x0f,1); //显示屏打开,光标显示,闪烁,检测忙信号
DisplayOneChar(6,0,minite/10+0x30);
DisplayOneChar(7,0,minite%10+0x30);}/**************液晶显示子函数4 *****************/void displayfun4(void)
{
WriteCommandLCM(0x0c,1); //显示屏打开,光标不显示,不闪烁,检测忙信号
DisplayListChar(0,0,str0);
DisplayListChar(0,1,str1);
DisplayOneChar(3,0,hour/10+0x30);
DisplayOneChar(4,0,hour%10+0x30); DisplayOneChar(6,0,minite/10+0x30);
DisplayOneChar(7,0,minite%10+0x30); DisplayOneChar(9,0,seconde/10+0x30);
DisplayOneChar(10,0,seconde%10+0x30);
DisplayOneChar(11,1,temp1/10+0x30);
DisplayOneChar(12,1,temp1%10+0x30);
DisplayOneChar(14,1,temp2/10+0x30);
WriteCommandLCM(0x0f,1); //显示屏打开,光标显示,闪烁,检测忙信号
DisplayOneChar(4,1,T/10+0x30);
DisplayOneChar(5,1,T%10+0x30);}/**************键盘扫描子函数******************/void keyscan(void)
{
uchar xx; //局部变量
P1=0xff;
if(P1!=0xff)
{
delay_LCM(30);
if(P1!=0xff)
{
xx=P1;
‘肆’ 单片机硬件方案怎么写
1、列出你的需求方案。
2、根据需求分析建立你的硬件方案。
3、硬件实现过程。
‘伍’ 求单片机开发方案
我有的,加我
‘陆’ 单片机的替代方案
高级单片机,arm内核有很多32位(
stm32
、ti的430系列等等)的,很多现成的带显示器、触摸屏的
开发板
淘宝有卖。
‘柒’ 单片机低功耗有什么好方案
找低功耗单片机.
找不到就采用间歇工作的方法.
‘捌’ 单片机控制LED方案
支持zhang_xin_gui3 你可以用8个口接8个三极管做行驱动再用相同的办法做8个列驱动 这样只用16个口即可控制8*8=64个led 而且只用了16个三极管 用8050或8550应该就可以 成本也很低
‘玖’ 求单片机科技制作的方案
石家庄英达单片机培训开发中心成立于2005年,中心以优质的服务,良好的合作空间,一流的技术水平.服务于电子行业各个领域.承各界朋友的大力支持,取得了辉煌的成绩.中心致力于以下几个方面工作:
1、承接各种单片机产品开发、电路设计、上位机软件开发
2、单片机系统应用培训(包括单片机程序设计和电路制作)
地 址: 石家庄市裕华
‘拾’ 谁帮我规划一个学习单片机的方案
两种学习思路;
我刚学完单片机,我就说说我导师教我我们的思路吧,首先用AT89S52上手,这是最简单,也是新手最容易上手的。价格便宜,我们学校批量购买就七八块钱一片,零售估计也贵不到哪去。首先搞清以它构成的小系统板的原理图,这是学习的一切前提(你要可以告诉我邮箱,我发给你,还有编程软件,下载软件,LED流水灯,8LED字数码管程序实例等一些程序)编程软件我用的keil3,下载用的Progisp,等到你能用LED8字数码管编出一个时钟程序时,单片机你就入门了。再接着用STC12C5410AD继续深一步学习,现在多说无益,等你入门后自己自然就找到感觉了,而且STC有自己专用的STC下载软件。
另一个学习思路就是:买一本配有光盘的单片机书,郭天祥的《51单片机C语言教程》是个不错的选择,里面有教学视屏,有软件,当然你就可以买他教学的配套系统版学习了,三百多,我有几个同学是这样学的,效果不错。
我觉得已经说得够实际够具体了,希望能帮到。