请选择 进入手机版 | 继续访问电脑版
查看: 840|回复: 0

AVR读取MC14021并入/串出移位寄存器程序

[复制链接]
发表于 2016-6-6 18:12:30 | 显示全部楼层 |阅读模式
我用ATMega8做个风扇移相调速和周波数调速试验,用INT0检测交流过零,一个LED显示调速的档级,另一个LED显示定时时间的档级。
操作按键用现成任天堂手柄,其内用MC14021并入/串出移位寄存器芯片来并行输入各个键值(0或1),再将结果串行输出到AVR中。

#include<macros.h>  
#include <avr/io.h>           // 由makefile里定 atmega8
#include "delayM8.h"
#define DDR_SPI  DDRB //改用atmega8:
#define DD_MISO 1        //端口PB1输入来自14021的输出(Q8)
#define DD_SCK         5        //端口PB5输出CLK 到14021作移位脉冲
#define DD_CS  2        //端口PB2输出 高低电平 到14021作并行输入操作(高)或移位输出操作(低)

unsigned char key_value;

PORTB = 0xfd;//应先先设电平
DDR_SPI= 0xFd;//再设方向,就不会发生电平瞬间变化 PB1是输入
PORTB=0x00;   //端口初始化

unsigned char read_4021(void)
{/*读4021的数据*/
unsigned char i,j;
unsigned char a=0;// 初始值清零 以后遇到某bit为零不再置0
PORTB|=(1<<DD_CS); //并行数据读入,转换使能=1 MC14021当P/S为“1”时,键值并行输入MC14021
asm("nop");        
PORTB|=(1<<DD_SCK);  //CLK high加在并行输入P1~P8的数据与时钟的上升沿同步地送入寄存器)
MyDelay_us(1);  //延时4.25uS
PORTB&=(~(1<<DD_CS));  //  pin9=0;//串行移出数据 下降沿 LOAD=0 ;轉成串列資料模式
MyDelay_us(1);
   if((PINB & 0x02)==0x02)  //读数据线要放到CLK上升沿前面的.因为一开始输出(Q8)有效
   a|=1<<(7);                   //a相应位置1                    

  for(i=1;i<8;i++)  
{ PORTB|=(1<<DD_SCK);          //pin10=1;//CLK high  ,Qn=Qn-1,时钟上升沿开始输出
   MyDelay_us(1);                 //脉冲顶部约4.25-6.5uS左右,延迟函数MyDelay_us(1);
PORTB &=(~(1<<DD_SCK));           //pin10=0;//CLK low ,Qn不变 时钟下降沿输出已经稳定可以读取了
   if((PINB & 0x02)==0x02)
   a|=1<<(7-i);                 //a相应位置1,
MyDelay_us(1);
}
return a;
}

void         main(void)
{
PORTB = 0xfd;//应先先设电平
DDR_SPI= 0xFd;//再设方向,就不会发生电平瞬间变化 PB1是输入
PORTB=0x00;   //端口初始化
....
while(1){
        key_value=read_4021();   // 读键盘
        //显示函数代码在此。。。
        //延迟处理在此。。。
        }
}
回复

使用道具 举报

您需要登录后才可以回帖 登录 | 加入因仑

本版积分规则

快速回复 返回顶部 返回列表