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

[复制链接]
1061|0
 楼主| ddllxxrr 发表于 2014-12-8 22:35 | 显示全部楼层 |阅读模式
MCP23S17是通过SPI接口同MPU连接。进行接口扩展,GPB6与GPB7引脚的按键可以控制GPA0~7及GPP0~1引脚连接的条形LED按不同方向滚动。

Proteus 仿真截图:

Atmel Studio6.2编译通过截图:

程序清单:
  1. /*
  2. * GccApplication30.c
  3. *
  4. * Created: 2014-12-8 21:25:56
  5. *  Author: Administrator
  6. */
  7. #define F_CPU 4000000UL
  8. #include <avr/io.h>
  9. #include <avr/interrupt.h>
  10. #include <util/delay.h>
  11. #include <stdint.h>

  12. #define MCP_ADDR 0x40
  13. #define IODIRA 0x00
  14. #define IODIRB 0x01
  15. #define GPPUB 0x0D
  16. #define GPIOA 0x12
  17. #define GPIOB 0x13

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

  20. uint8_t Demo_OP_No = 0;

  21. void SPI_MasterInit()
  22. {
  23.         DDRB = 0B10110000;PORTB = 0xFF;
  24.         SPCR |=_BV(SPE)|_BV(MSTR)|_BV(SPR0);
  25.        
  26. }

  27. uint8_t SPI_Transmit(uint8_t dat)
  28. {
  29.         SPDR = dat;
  30.         while(!(SPSR & _BV(SPIF)));
  31.         return SPDR;
  32. }

  33. void Write_MCP23S17(uint8_t Device_addr,uint8_t Reg_addr,uint8_t CD)
  34. {
  35.         SPI_EN();
  36.         SPI_Transmit(Device_addr);
  37.         SPI_Transmit(Reg_addr);
  38.         SPI_Transmit(CD);
  39.         SPI_DI();
  40. }

  41. void Reda_MCP23S17(uint8_t Device_addr,uint8_t Reg_addr,uint8_t * Dat)
  42. {
  43.         SPI_EN();
  44.         SPI_Transmit(Device_addr|0x01);
  45.         SPI_Transmit(Reg_addr);
  46.         *Dat=SPI_Transmit(0xFF);
  47.         SPI_DI();
  48. }

  49. void Initialise_MCP23S17()
  50. {
  51.         Write_MCP23S17(MCP_ADDR,IODIRA,0x00);
  52.         Write_MCP23S17(MCP_ADDR,IODIRB,0xF0);
  53.         Write_MCP23S17(MCP_ADDR,GPIOA,0x00);
  54.         Write_MCP23S17(MCP_ADDR,GPIOB,0x00);
  55. }
  56. void Key_Handle()
  57. {
  58.         uint8_t Key_Port_Status;
  59.         Reda_MCP23S17(MCP_ADDR,GPIOB,&Key_Port_Status);
  60.         if((Key_Port_Status & 0x80)==0x00)Demo_OP_No = 0;
  61.         else
  62.         if((Key_Port_Status & 0x40)==0x00)Demo_OP_No = 1;
  63. }

  64. int main(void)
  65. {
  66.     uint8_t i; uint16_t Pattern;
  67.         DDRB = 0xFF;
  68.         SPI_MasterInit();
  69.         Initialise_MCP23S17();
  70.         while(1)
  71.     {
  72.         //TODO:: Please write your application code
  73.                 if(Demo_OP_No == 0)
  74.                 {
  75.                    Pattern = 0xFFFE;
  76.                    for(i=0;i<10;i++)
  77.                    {
  78.                            Write_MCP23S17(MCP_ADDR,GPIOA,(uint8_t)Pattern);
  79.                            Write_MCP23S17(MCP_ADDR,GPIOB,(uint8_t)(Pattern>>8));
  80.                            Pattern = Pattern << 1 | 0x0001;
  81.                            Key_Handle();
  82.                            if(Demo_OP_No != 0)break;
  83.                            _delay_ms(10);
  84.                    }
  85.                 }
  86.                    else
  87.                    {
  88.                            Pattern = 0x01FF;
  89.                            for(i=0;i<10;i++)
  90.                            {
  91.                                     Write_MCP23S17(MCP_ADDR,GPIOA,(uint8_t)Pattern);
  92.                                    Write_MCP23S17(MCP_ADDR,GPIOB,(uint8_t)(Pattern>>8));
  93.                                    Pattern = Pattern >> 1 | 0x0200;
  94.                                    Key_Handle();
  95.                                    if(Demo_OP_No != 1)break;
  96.                                    _delay_ms(10);
  97.                            }
  98.                    }
  99.          }
  100. }



本帖子中包含更多资源

您需要 登录 才可以下载或查看,没有账号?注册

×
您需要登录后才可以回帖 登录 | 注册

本版积分规则

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

2404

主题

7001

帖子

68

粉丝
快速回复 在线客服 返回列表 返回顶部