树莓派模块-LCD1602+RGB模块 参考程序

树莓派模块-LCD1602+RGB模块 参考程序_第1张图片/*
 * 本程序是使用Arduino来驱动“RGB1602 Module For RPI”
 * 模块是使用的是IIC总线协议MCP23017芯片扩展的IO来检测按键输入
 * 及驱动lcd1602屏幕,RGB三色背光是IO独立控制的。
 * 初始化后闪动光标,按不同按键显示不同内容
 * 调用了iic总线库"Wire.h"
 * IDE环境:Arduino 1.6.5
 */


#include "Wire.h"  //调用iic总线库


char inputA = 0x00; //按键输入字符初始化赋值
char outputA = 0x00; //A端口输出字符初始化赋值
char outputB = 0x00; //B端口输出字符初始化赋值
char cache = 0x00; //缓存初始化赋值


char str1[] = "abcdef ABCDEF";  //定义不同字符串
char str2[] = "1234^-M_M-^789";
char str3[] = "Welcome to";
char str4[] = "smilefrog.net";
char str5[] = "Please press";
char str6[] = "the button";


int LCD1602_RS = 7;//LCD1602对应的MCP23017的引脚
int LCD1602_RW = 6;//LCD1602对应的MCP23017的引脚
int LCD1602_EN = 5;//LCD1602对应的MCP23017的引脚
int DB[] = { 1, 2, 3, 4};//LCD1602的数据脚(D7,D6,D5,D4)对应MCP23017的引脚
int r = 6, g = 7, b = 0;//LCD1602的背光控制引脚,r=A6,g=A7,b=B0


int Address = 0x20;  //OLED 12864器件7位地址


void key_scan(void)  //按键输入函数
{
  char input1 = 0x00;
  char input2 = 0x00;
  Wire.beginTransmission(Address);
  Wire.write(0x12); // 设置MCP23017芯片GPIOA的地址  
  Wire.endTransmission();


  Wire.requestFrom(Address, 8); // 读取8位数据
  input1 = Wire.read(); // 将读取到的数据赋值到inputA
  
  delay(10);
  
  Wire.beginTransmission(Address);
  Wire.write(0x12); // 设置MCP23017芯片GPIOA的地址  
  Wire.endTransmission();
  
  Wire.requestFrom(Address, 8); // 读取8位数据
  input2 = Wire.read(); // 将读取到的数据赋值到inputA
  
  if(input1==input2)
    inputA = input2;
}
void writeA(int x, bool y)//芯片GPIOA输出函数
{
  switch (x)
  {
    case 0: cache = 0x01;
      break;
    case 1: cache = 0x02;
      break;
    case 2: cache = 0x04;
      break;
    case 3: cache = 0x08;
      break;
    case 4: cache = 0x10;
      break;
    case 5: cache = 0x20;
      break;
    case 6: cache = 0x40;
      break;
    case 7: cache = 0x80;
      break;
    default: break;
  }
  outputA = (outputA & ~cache) | (y << x);
  Wire.beginTransmission(Address);
  Wire.write(0x12); // address port A
  Wire.write(outputA);  // value to send
  Wire.endTransmission();
}
void writeB(int x, bool y)//芯片GPIOB输出函数
{
  switch (x)
  {
    case 0: cache = 0x01;
      break;
    case 1: cache = 0x02;
      break;
    case 2: cache = 0x04;
      break;
    case 3: cache = 0x08;
      break;
    case 4: cache = 0x10;
      break;
    case 5: cache = 0x20;
      break;
    case 6: cache = 0x40;
      break;
    case 7: cache = 0x80;
      break;
    default: break;
  }
  outputB = (outputB & ~cache) | (y << x);
  Wire.beginTransmission(Address);
  Wire.write(0x13); // address port B
  Wire.write(outputB);  // value to send
  Wire.endTransmission();
}
void LCD_Command_Write(char command)//写LCD1602的命令
{
  char i, temp;
  writeB( LCD1602_RS, 0);
  writeB( LCD1602_RW, 0);


  temp = command & 0xf0;
  for (i = 0; i < 4; i++)
  {
    writeB(DB[i], (temp << i) & 0x80);
  }


  writeB( LCD1602_EN, 1);
  writeB( LCD1602_EN, 0);


  temp = command << 4;
  for (i = 0; i < 4; i++)
  {
    writeB(DB[i], (temp << i) & 0x80);
  }


  writeB( LCD1602_EN, 1);
  writeB( LCD1602_EN, 0);
}


void LCD_Init(void) //LCD1602初始化
{
  //  delay(50);
  LCD_Command_Write(0x28);//4线 2行 5x7
  delay(5);
  LCD_Command_Write(0x06);//递增
  delay(5);
  LCD_Command_Write(0x0f);//显示并闪光标0x0 + [1,D(显示),C(开光标),B(光标闪)]
  delay(5);
  LCD_Command_Write(0x01);//   清屏
  delay(5);


  /*************诡异的初始化内容,否则显示不正常***************/
  LCD_Command_Write(0x83);
  LCD_Command_Write(0x80);
  LCD_Command_Write(0x82);
  LCD_Command_Write(0x83);
  /***********************************************************/


  LCD_Command_Write(0x01);//   清屏
  delay(5);
}


void LCD_Data_Write(char dat)//写LCD1602的数据
{
  char i = 0, temp;
  writeB( LCD1602_RS, HIGH);
  writeB( LCD1602_RW, LOW);


  temp = dat;
  for (i = 0; i < 4; i++)
  {
    writeB(DB[i], (temp << i) & 0x80);
  }


  writeB( LCD1602_EN, HIGH);
  writeB( LCD1602_EN, LOW);


  temp = dat << 4;
  for (i = 0; i < 4; i++)
  {
    writeB(DB[i], (temp << i) & 0x80);
  }


  writeB( LCD1602_EN, HIGH);
  writeB( LCD1602_EN, LOW);
}


void LCD_SET_XY( int x, int y )//设置显示位置
{
  char address;
  if (x == 0)    address = 0x80 + y;
  else if (1 == x)   address = 0xC0 + y;
  LCD_Command_Write(address);
}


void LCD_Write_Char( int x, int y, char dat)//写字节
{
  LCD_SET_XY( x, y );
  LCD_Data_Write(dat);
}


void LCD_Write_String(int m, int n, char *s) // 写字符串
{
  LCD_SET_XY( m, n );    //设置地址
  while (*s)             //写字符串
  {
    LCD_Data_Write(*s);
    s ++;
  }
}


void setup (void)
{
  //  Serial.begin(9600);//初始化串口
  Wire.begin(); //初始化iic


  Wire.beginTransmission(Address);//设置MCP23017芯片GPIOA方向
  Wire.write(0x00); // IODIRA register
  Wire.write(0x1f); // set  port A to ( 0001 1111 )
  Wire.endTransmission();


  Wire.beginTransmission(Address);//设置MCP23017芯片GPIOA上拉
  Wire.write(0x0c); // GPPUA register
  Wire.write(0x1f); // set  port GPPUA to ( 0001 1111 )
  Wire.endTransmission();
  
  writeA(r, 1);//背光闪动
  delay(400);
  writeA(r, 0);
  writeA(g, 1);
  delay(400);
  writeA(g, 0);
  writeB(b, 1);
  delay(400);
  writeA(r, 1); //消隐
  writeA(g, 1);
  writeB(b, 1);
  
  Wire.beginTransmission(Address);//设置MCP23017芯片GPIOB为输出
  Wire.write(0x01); // IODIRB register
  Wire.write(0x00); // set all of port B to outputs
  Wire.endTransmission();


  LCD_Init();//初始化LCD1602
  delay(10);
  
  LCD_Command_Write(0x01);//   清屏
  delay(10);
  LCD_Write_String(0, 2, str5); //第1行,第1个地址起
  LCD_Write_String(1, 0, str6); //第1行,第1个地址起
}


void loop (void)
{
  key_scan();
  switch (inputA & 0x1f)
  {
    case 0x1e:
      {
        writeB(b, 0);
        writeA(r, 1);
        delay(500);
        writeA(r, 0);
        writeA(g, 1);
        delay(500);
        writeA(g, 0);
        writeB(b, 1);
        delay(500);
        writeA(r, 1); //消隐
        writeA(g, 1);
        writeB(b, 1);
      } break;
    case 0x1d:
      {
        LCD_Command_Write(0x01);//   清屏
        delay(10);
        LCD_Write_String(0, 0, str3); //第1行,第1个地址起
        LCD_Write_String(1, 1, str4); //第2行,第2个地址起
      } break;
    case 0x1b:
      {
        LCD_Command_Write(0x01);//   清屏
        delay(10);
        LCD_Write_String(0, 0, str1); //第1行,第1个地址起
        LCD_Write_String(1, 1, str2); //第2行,第2个地址起
      } break;
    case 0x17:
      {
        LCD_Command_Write(0x01);
        delay(10);
        LCD_Write_Char(0, 0, 'A'); //第1行,第1个地址
        LCD_Write_Char(0, 1, 'a'); //第1行,第2个地址
        LCD_Write_Char(0, 2, 'B'); //第1行,第3个地址
        LCD_Write_Char(0, 3, 'b'); //第1行,第4个地址
      } break;
    case 0x0f:
      {
        LCD_Command_Write(0x01);
        delay(10);
        LCD_Write_Char(1, 5, 'A'); //第2行,第5个地址
        LCD_Write_Char(1, 6, 'a'); //第2行,第7个地址
        LCD_Write_Char(1, 7, 'B'); //第2行,第8个地址
        LCD_Write_Char(1, 8, 'b'); //第2行,第9个地址
      } break;
    default: break;
  }
}


你可能感兴趣的:(树莓相关)