打印
[Atmel]

用AtmelStudio6.2跑mega16例程(67)SPI方式扩展IO口

[复制链接]
880|0
手机看帖
扫描二维码
随时随地手机跟帖
跳转到指定楼层
楼主
MCP23S17是通过SPI接口同MPU连接。进行接口扩展,GPB6与GPB7引脚的按键可以控制GPA0~7及GPP0~1引脚连接的条形LED按不同方向滚动。

Proteus 仿真截图:

Atmel Studio6.2编译通过截图:

程序清单:
/*
* GccApplication30.c
*
* Created: 2014-12-8 21:25:56
*  Author: Administrator
*/
#define F_CPU 4000000UL
#include <avr/io.h>
#include <avr/interrupt.h>
#include <util/delay.h>
#include <stdint.h>

#define MCP_ADDR 0x40
#define IODIRA 0x00
#define IODIRB 0x01
#define GPPUB 0x0D
#define GPIOA 0x12
#define GPIOB 0x13

#define SPI_EN() PORTB &=~_BV(PB4)
#define SPI_DI() PORTB |= _BV(PB4)

uint8_t Demo_OP_No = 0;

void SPI_MasterInit()
{
        DDRB = 0B10110000;PORTB = 0xFF;
        SPCR |=_BV(SPE)|_BV(MSTR)|_BV(SPR0);
       
}

uint8_t SPI_Transmit(uint8_t dat)
{
        SPDR = dat;
        while(!(SPSR & _BV(SPIF)));
        return SPDR;
}

void Write_MCP23S17(uint8_t Device_addr,uint8_t Reg_addr,uint8_t CD)
{
        SPI_EN();
        SPI_Transmit(Device_addr);
        SPI_Transmit(Reg_addr);
        SPI_Transmit(CD);
        SPI_DI();
}

void Reda_MCP23S17(uint8_t Device_addr,uint8_t Reg_addr,uint8_t * Dat)
{
        SPI_EN();
        SPI_Transmit(Device_addr|0x01);
        SPI_Transmit(Reg_addr);
        *Dat=SPI_Transmit(0xFF);
        SPI_DI();
}

void Initialise_MCP23S17()
{
        Write_MCP23S17(MCP_ADDR,IODIRA,0x00);
        Write_MCP23S17(MCP_ADDR,IODIRB,0xF0);
        Write_MCP23S17(MCP_ADDR,GPIOA,0x00);
        Write_MCP23S17(MCP_ADDR,GPIOB,0x00);
}
void Key_Handle()
{
        uint8_t Key_Port_Status;
        Reda_MCP23S17(MCP_ADDR,GPIOB,&Key_Port_Status);
        if((Key_Port_Status & 0x80)==0x00)Demo_OP_No = 0;
        else
        if((Key_Port_Status & 0x40)==0x00)Demo_OP_No = 1;
}

int main(void)
{
    uint8_t i; uint16_t Pattern;
        DDRB = 0xFF;
        SPI_MasterInit();
        Initialise_MCP23S17();
        while(1)
    {
        //TODO:: Please write your application code
                if(Demo_OP_No == 0)
                {
                   Pattern = 0xFFFE;
                   for(i=0;i<10;i++)
                   {
                           Write_MCP23S17(MCP_ADDR,GPIOA,(uint8_t)Pattern);
                           Write_MCP23S17(MCP_ADDR,GPIOB,(uint8_t)(Pattern>>8));
                           Pattern = Pattern << 1 | 0x0001;
                           Key_Handle();
                           if(Demo_OP_No != 0)break;
                           _delay_ms(10);
                   }
                }
                   else
                   {
                           Pattern = 0x01FF;
                           for(i=0;i<10;i++)
                           {
                                    Write_MCP23S17(MCP_ADDR,GPIOA,(uint8_t)Pattern);
                                   Write_MCP23S17(MCP_ADDR,GPIOB,(uint8_t)(Pattern>>8));
                                   Pattern = Pattern >> 1 | 0x0200;
                                   Key_Handle();
                                   if(Demo_OP_No != 1)break;
                                   _delay_ms(10);
                           }
                   }
         }
}



相关帖子

发新帖 我要提问
您需要登录后才可以回帖 登录 | 注册

本版积分规则

个人签名:http://shop34182318.taobao.com/ http://shop562064536.taobao.com

2398

主题

6955

帖子

67

粉丝