📄 anglemachine.c
字号:
*/
#include "12f629.h"
#use delay(CLOCK=4000000,RESTART_WDT)
#use fast_io(A)
#define NO 2 //连接74HC595的个数
#define CPR 72 //36000/500光电编码器分辨率
#define GPIO 0x5 //GP口地址
#define WPU 0x95 //
#define OSCCAL 0x90 //
#bit DOUT=GPIO.0
#bit CLK =GPIO.1
#bit INA =GPIO.2
#bit INB =GPIO.3
#bit STR =GPIO.4
#bit INZ =GPIO.5
int led_data[2]; //缓存74HC595显示数据
int bcd[5]={11,11,11,11,11}; //5位BCD码
int led_bit=0; //当前显示位
long count=0; //16位计数器
long count_new=0; //计数器新值
long count_old=0; //计数器旧值
short direct=1; //转动方向
int const segs[13]={0xfc,0x60,0xda,0xf2,0x66,0xb6,0xbe,0xe0,0xfe,0xf6,0x0,0x92,0x2};
int const digs[4]={0x7f,0xbf,0xdf,0xef};
//int16到5位BCD的转换
void int16_to_bcd5(long counter, int * bcd5)
{
const long c[5]={10000,1000,100,10,1};
int i;
long k;
for(i=0;i<5;i++)
{
k=0;
while(counter>=c[i])
{
counter-=c[i];
++k;
}
bcd5[i]= k;
}
}
//将数据写入74HC595
void out_595(int* eo)
{
int i;
CLK=0;
STR=0;
for(i=1;i<=NO*8;++i)
{
if((*(eo)&0x01)==0) //将最低位输出到DOUT
DOUT=0;
else
DOUT=1;
rotate_right(eo,NO); //数组循环右移一位
CLK=1;
delay_cycles(2);
CLK=0;
}
STR=1; //输出到数码管
delay_cycles(2);
STR=0;
}
//LED数码管译码显示
void out_led(int c)
{
led_data[1]=0xf0;
out_595(led_data); //数码管消隐
led_data[0]=segs[bcd[c]];
led_data[1]=digs[c];
if(led_bit==2)
bit_set(led_data[0],0); //显示小数点
out_595(led_data); //刷新数码管数据
}
//计算计数器差值
long get_margin(long c_new,long c_old)
{
if(c_new<c_old) //如果计数器溢出翻转
return(65536-c_old+c_new);
else
return(c_new-c_old);
}
//根据差值、旧角度值、转动方向计算新的角度值
long get_count(long c,long ct,short d)
{
if(d==1) //如果正转
{
ct=c+ct;
if(ct>=3200)
ct=ct%3200;
}
else //如果反转
{
if(c>ct)
ct=3200-(c-ct);
else
ct=ct-c;
}
return(ct);
}
//EXT中断处理,根据脉冲相位判断转动方向
#int_ext
void get_data()
{
if(bit_test(INB,0)) //A相跳高时,若B相为高则正转
direct=1;
else //B相为低则反转
direct=0;
}
//主程序
void main()
{
disable_interrupts(GLOBAL); //关总中断
setup_comparator(NC_NC_NC_NC); //关闭比较器,全部设成IO
port_a_pullups(FALSE);
*OSCCAL=0xff; //全速运行
set_tris_a(0b00101100); //初始化IO口
ext_int_edge(L_TO_H); //设置成上跳沿触发中断
setup_timer_1(T1_EXTERNAL|T1_DIV_BY_1);
set_timer1(0);
enable_interrupts(INT_EXT); //开EXT中断
enable_interrupts(GLOBAL); //开总中断
while (1)
{
long cou;
long margin;
restart_wdt();
count_new=get_timer1(); //获得新的计数值
margin=get_margin(count_new,count_old); //获得差值
count_old=count_new; //刷新旧的计数值
count=get_count(margin,count,direct); //获得新的角度值
cou=(count*11.25);
if((cou%10)>=5) //四舍五入
cou+=10;
int16_to_bcd5(cou,bcd);
if(cou<10000) //消去数码管左边多余的零,节电
bcd[0]=10;
if(cou<1000)
bcd[1]=10;
out_led(led_bit);
led_bit++;
if(led_bit>=4) //共扫描4位数码管
led_bit=0;
}
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -