#include<reg52.h>
#include<zlg7289.h>
/************************************************************/
#define uint unsigned int
#define uchar unsigned char
sbit P00=P0^0//底座旋转舵机
sbit P01=P0^1//腰部舵机
sbit P02=P0^2//肘部舵机
sbit P03=P0^3//腕部舵机
sbit P04=P0^4//夹持舵机
uchar Key=0xff//默认键值
uchar k=0xff
uchar flag=0
uchar dat
uchar M=11
uchar dj0,dj1,dj2,dj3,dj4
uchar a=0
uchar c=0
uchar beep=1
/***********************************************************/
void Delay(uchar n)//毫秒延时
{
uint i,j
for(i=ni>0i--)
for(j=0j<1140j++)
}
void Init_Timer0(void)
{
TMOD |= 0x01
TH0=0xff //定时器初值,定时100us
TL0=0x9c
EA=1
ET0=1
TR0=1
}
void INT0_SVC() interrupt 0
{
Key = ZLG7289_Key()
k = Key//Key 的值复制到临时变量k 中
Key = 0xFF//Key 恢复为无按键状态
flag=1
}
void Init_zlg(void)
{
Delay(10)//延时30ms,等待ZLG7289 复位完毕
ZLG7289_Init(4)//调用ZLG7289 的初始化函数
Delay(20)
ZLG7289_Reset()
Delay(10)
}
void Timer0_isr(void) interrupt 1 using 1
//中断函数内部太过复杂,影响定时器计时精度,堆栈是否会溢出出问题?有待测试...
{
a+=1
c+=1
TH0=0xff
TL0=0x9c
if(a==M) //高电平持续时间
{
a=0
beep=0
}
if(c==200) //低电平持续时间为(200-M)*100us
{
a=c=0
beep=1
}
}
void mov(uchar t ,uchar p,uchar n)//单步动作完成函数 ,t为控制执行时间参数,n为舵机编号选择
{
uchar i,j
M=p//所需位置信息赋给舵机脉宽变量
for(i=0i<150i++)
{
if(flag)
break
for(j=0j<tj++)
{
switch(n)
{
case 0:{P00=beepdj0=pbreak}
case 1:{P01=beepdj1=pbreak}
case 2:{P02=beepdj2=pbreak}
case 3:{P03=beepdj3=pbreak}
case 4:{P04=beepdj4=pbreak}
default:break
}
}
}
}
void auto_mov()//自动执行一串动作
{
mov(100,5,0)
mov(60,7,1)
mov(100,22,3)
mov(200,17,4)
mov(60,10,1)
mov(60,8,2)
mov(100,22,0)
mov(80,7,1)
mov(80,10,2)
// mov(100,20,3)
mov(200,8,4)
mov(60,11,1)
mov(60,11,2)
mov(60,18,3)
}
void key_test()
{
for ()
{
flag=0
if ( k != 0xFF ) //通过临时变量k 判断是否有键按下,有则显示出来
{
dat = k / 10
ZLG7289_Download(1,2,0,dat)
dat = k - dat * 10
ZLG7289_Download(1,3,0,dat)
//以下部分调节高电平脉宽,控制舵机转角
switch(k)
{
case 0:{ if(dj0>=5)dj0--M=dj0break}
case 1:{ if(dj1>=5)dj1--M=dj1break}
case 2:{ if(dj2>=5)dj2--M=dj2break}
case 3:{ if(dj3>=5)dj3--M=dj3break}
case 4:{ if(dj0<=23)dj0++M=dj0break}
case 5:{ if(dj1<=23)dj1++M=dj1break}
case 6:{ if(dj2<=23)dj2++M=dj2break}
case 7:{ if(dj3<=23)dj3++M=dj3break}
case 8:{ if(dj4<=23)dj4++M=dj4break}
case 9:{ if(dj4>=5)dj4--M=dj4break}
case 10:{auto_mov()k=0xffbreak}
default:break
}
while(k==0||k==4)
{
P00=beep
if(flag)
break
}
while(k==1||k==5)
{
P01=beep
if(flag)
break
}
while(k==2||k==6)
{
P02=beep
if(flag)
break
}
while(k==3||k==7)
{
P03=beep
if(flag)
break
}
while(k==8||k==9)
{
P04=beep
if(flag)
break
}
}
Delay(5)
}
}
void main()
{
Init_Timer0() //初始化定时器设置
Init_zlg() //初始化周立功7289
IT0 = 1//负边沿触发中断
EX0 = 1
dj0=dj1=dj2=dj3=dj4=M
while(k==0xff)
P00=P01=P02=P03=beep
key_test()
}
在keil v5 运行下,出现
错误提示:
Build target 'Target 1'
compiling 1.c...
1.c(5): warning C318: can't open file 'ZLG7289.h'
1.C(41): warning C206: 'ZLG7289_Key': missing function-prototype
1.C(49): warning C206: 'ZLG7289_Init': missing function-prototype
1.C(49): error C267: 'ZLG7289_Init': requires ANSI-style prototype
Target not created
求高手帮手
这是数码管显示驱动及键盘扫描管理芯片,在Proteus中没有这一款仿真芯片。那么怎么解决这个问题呢。1、直接根据ZLG7289B芯片的PDF文件,根据电路给出的参考电路,完成原理图的制作,完成后根据参数调试电路。一般而言,芯片中给出的原理图资料,都是经过过程测试,所以,你根据电路图设计,就不会有问题。
2、数码管的驱动,你可以用锁存器,或者三极管控制来实现驱动。按键扫描的程序部分,通过单片机软件程序来实现检测。此种方案是单片机数码管和按键最长的设计,结构简单,功能一样。
这是2个不同的方案,你根据具体的设计,来选择你需要的
频率测量的方法常用的有测频法和测周法两种。
测频法的基本思想是让计数器在闸门信号的控制下计数1秒时间,计数结果是1秒内被测信号的周期数,即被测信号的频率。若被测信号不是矩形脉冲,则应先变换成同频率的矩形脉冲。测频法的原理框图如图所示。
图中,秒脉冲作为闸门信号,当其为高电平时,计数器计数;低电平时,计数器停止计数。显然,在同样的闸门信号作用下,被测信号的频率越高,测量误差越小。当被测频率一定时,闸门信号高电平的时间越长,测量误差越小。但是闸门信号周期越长,测量的响应时间也越长。
2、当被测信号频率较低时,为保证测量精度,常采用测周法。即先测出被测信号的周期,再换算成频率。测周法的实质是把被测信号作为闸门信号。
在它的高电平的时间内,用一个标准频率的信号源作为计数器的时钟脉冲。若计数结果为N,标准信号频率为f1,则被测信号的周期为:T = T1·N。被测信号的频率为:f = 1/T1·N = f1/N。
利用测周法所产生的最大绝对误差,显然也等于±1个标准信号周期。如果被测信号周期的真值为T真= T1·N,则T测= T1·(N±1)σmax= (f测-f真)/ f真= T真/T测 – 1=±1/(N±1)由上式可知,对于一定的被测信号,标准信号的频率越高,则N的值越大,因而相对误差越小。
3、低频段的测量,鉴于上述困难,对于低频信号,为了达到规定的精度,要采取一些比较特殊的方法。例如,可考虑将被测信号倍频后再用测频法测量。
或将闸门信号展宽。由于倍频电路比较复杂,所以一般采用后一种方法,实际上闸门信号展宽与被测信号倍频在效果上是相同的。
闸门信号展宽比较容易做到,例如采用分频电路就可以实现。若闸门信号高电平时间从1秒展宽到10秒,则相对误差可以按比例下降,但响应时间也增大相同的比例。
4、显示方式:共用右边四个数码管,左三个显示数据,最右端一个显示单位,为0时单位为Hz,为1时单位为Khz
5、代码:
//#include<c8051F330.h>
#include<ZLG7289.h>
#include<init.h>
#define uint unsigned int
uint a,b,c,d
unsigned long x
unsigned long count
unsigned char flag=0
void Timer0_Init()interrupt 1
{
TH0=(65535-10000)/256
TL0=(65535-10000)%256
if(++count==40)
{
count=0
TR1=0
x=TH1*256+TL1
TH1=0
TL1=0
TR1=1
flag=1
}
}
void show(void)
{if(x>=10&&x<100)
{
a=0
b=x*10%100
c=x/10
d=x%10
ZLG7289_Download(1,7,0,a)
ZLG7289_Download(1,6,0,b)
ZLG7289_Download(1,5,1,d)
ZLG7289_Download(1,4,0,c)
}
else if(x>=100&&x<1000)
{
a=0
b=x/100
c=x%100/10
d=x%10
ZLG7289_Download(1,7,0,a)
ZLG7289_Download(1,6,1,d)
ZLG7289_Download(1,5,0,c)
ZLG7289_Download(1,4,0,b)
}
else if(x>=1000&&x<10000)
{
a=x/1000
b=x%1000/100
c=x%100/10
d=1
ZLG7289_Download(1,7,0,d)
ZLG7289_Download(1,6,0,c)
ZLG7289_Download(1,5,0,b)
ZLG7289_Download(1,4,1,a)
}
}
main(void)
{
system_init()
systemclk_init()
port_init()
ZLG7289_Init(40)
ZLG7289_Reset()
timer_init()
while(1)
{
if(flag==1)
{
show()
flag = 0
}
}}
#include <C8051F330.h>
#include <port.h>
void system_init()
{
PCA0MD&=~0x40
}
void systemclk_init()
{
OSCICL=OSCICL+42//设置内部振荡器为24MHZ
OSCICN|=0x01 //内部振荡器4分频
}
void port_init()
{
P0SKIP=0x00 //跳过P0.0做INT0.P0.1做INT1(P0.6,P0.7模拟输出不跳)
P1SKIP=0x00 //跳过P1.2,P1.3,P1.4
XBR0=0x00 //交叉开关使能UART0
XBR1=0x60 //打开交叉开关
//IT01CF=0x10 //INT0配置在P0.0,INT1配置在P0.1
P0MDIN=0xFF //数字输入
P1MDIN=0xFF
P0MDOUT=0xFF//推挽
P1MDOUT=0xFF
}
void timer_init()
{
TMOD=0X51
TH0=(65535-2500)/256
TL0=(65535-2500)%256
EA=1
ET0=1
TR1=1
TR0=1
}
#ifndef __port_H_
#define __port_H_
void system_init(void)
void systemclk_init(void)
void port_init(void)
void timer_init(void)
#endif
欢迎分享,转载请注明来源:内存溢出
评论列表(0条)