Proteus仿真-ARM7单片机-输入/输出端口GPIO编程02


作者:Justin

博客地址:http://blog.sina.com.cn/lonlycorner520  

点击阅读原文,可以看到完成的笔记系列


总算是好了~~

不过期间还是碰到点小问题~~

不过都一一解决了~~

ARM~~

确实不一样啊~~

一、输入/输出端口GPIO编程一—(02)、控制LCD1602显示~~

废话不多说了~~直接上图~~

然后是程序~~

当然,笔者能力有限,也不会像别的开发板那样,专门录制一套视频来详细讲解,在此笔者用文字的形式来替代视频讲解,尽可能的讲解详细一点,让更多的初学者能学会用单片机来做自动化控制。

MDK1_2.c

//------------------------------------------------------------------------------
//这个当然是主函数了
#include"lpc210x.h"
#include"macroandconst.h"
#include"delay.h"
#include"lcdinit.h"
//------------------------------------------------------------------------------
//很让人蛋疼~~这里貌似不能加上const~~
//怎么会出现这种情况呢~~等下次遇到了再解决~~
uchar title0[]="Designed by ";
uchar title1[]="_Justin";
//------------------------------------------------------------------------------
//端口初始化函数
void port_init()
{
 PINSEL0=0X00000000;        //所有引脚连接至GPIO
 PINSEL1=0X00000000;

 IODIR=0X000007FF;        //设置为输出~~当然,如果你要读LCD1602里面的数据~~那就有输出有输入呗~~
             //自己再改动吧~~
}
int main()
{
 port_init();
 lcd_init();
 lcd_display_string(0,0,title0,12);
 lcd_display_string(1,7,title1,7);
 while(1);
}

LcdInit.c

//------------------------------------------------------------------------------
//LCD初始化函数~~For ARM
//这里也包括了LCD的显示函数
#include"lpc210x.h"
#include"macroandconst.h"
#include"delay.h"
#include"bit.h"
//------------------------------------------------------------------------------
//RS、RW、EN引脚高低电平的定义
//这里不一定非要这么写,我也是因为以前用过ATMEGA16,这样写方便了很多,但是这里由于IOSET、IOCLR的寄存器写1有效,写0无效
//所以根本不用担心~~所以也是可以直接赋值的~~
//还有,这里有个很重要的问题就是! SET_BIT() 不管是把引脚拉高或者置低,都要用到
//你懂得~~只有在IOSET、IOCLR寄存器写1才能达到置1和清零的作用
#define lcd_rs_1 SET_BIT(IOSET,8)     //数据命令选择
#define lcd_rs_0 SET_BIT(IOCLR,8)
#define lcd_rw_1 SET_BIT(IOSET,9)     //读写命令选择
#define lcd_rw_0 SET_BIT(IOCLR,9)
#define lcd_en_1 SET_BIT(IOSET,10)     //使能信号
#define lcd_en_0 SET_BIT(IOCLR,10)
//------------------------------------------------------------------------------
#define busy (1<<7)        //忙检测
//------------------------------------------------------------------------------
//忙检测函数
void lcd_check_busy()
{
 IOCLR=0xff;          //把数据口都拉低
 IODIR=0x700;         //这里设置RS、RW、E为输出口,数据口为输入口
 lcd_rs_0;
 lcd_rw_1;
 while(IOPIN&busy)         //IOPIN反映了外部环境对器件的影响,也就是检测PB7是否为0。如果为0则中断while循环~~
 {
  lcd_en_0;
  delay_1ms();
  lcd_en_1;
  delay_1ms();
 
 lcd_en_0;
 IODIR=0x7ff;         //设置RS、RW、E和数据口都为输出口
}
//------------------------------------------------------------------------------
//LCD写数据函数
void lcd_write_data(uchar dat)
{
  lcd_check_busy();
  lcd_rs_1;
  lcd_rw_0;
  IOCLR=0xff;          //先要清零
  IOSET=dat;             //再送数据
  lcd_en_1;
  delay_1ms();
  lcd_en_0;
}
//------------------------------------------------------------------------------
//LCD写指令函数
//其中flag的作用是为0不进行忙检测,为非0则进行忙检测
void lcd_write_command(uchar com,uchar flag)
{
  if(flag)
   lcd_check_busy();
  lcd_rs_0;
  lcd_rw_0;
  IOCLR=0xff;          //先要清零,也就是将引脚都拉低
  IOSET=com;          //然后再送数据
  lcd_en_1;
  delay_1ms();          //送一个延时
  lcd_en_0;           //锁存

}
//------------------------------------------------------------------------------
//LCD初始化函数
void lcd_init()
{
  lcd_write_command(0x38,0);       //8位数据传送,两行显示,5*7字形,不检测忙信号
  delay_nms(5);
  lcd_write_command(0x38,0);
  delay_nms(5);
  lcd_write_command(0x38,0);
  delay_nms(5);
  lcd_write_command(0x38,1);      //8位数据传送,两行显示,5*7字形,检测忙信号
  lcd_write_command(0x08,1);      //关闭显示,检测忙信号
  lcd_write_command(0x01,1);      //清屏,检测忙信号  delay_1ms();
  lcd_write_command(0x06,1);      //显示光标右移设置,检测忙信号
  lcd_write_command(0x0c,1);      //显示屏打开,光标不显示,不闪烁,检测忙信号
}
//------------------------------------------------------------------------------
//LCD显示一个字节函数
void  lcd_display_char(uchar row,uchar add,uchar dat)
{
  switch(row)
  {
  case 0:
    lcd_write_command(0x80+add,1);
    lcd_write_data(dat);
    break;
    //------------------------------------------------------------------------------
   case 1:
    lcd_write_command(0x80+0x40+add,1);
    lcd_write_data(dat);
    break;
  default:
    break;
  }
}
//------------------------------------------------------------------------------
//LCD显示多个字节函数
void  lcd_display_string(uchar row,uchar add,uchar *s,uchar num)
{
  uchar i;
  switch(row)
  {
  case 0:
    lcd_write_command(0x80+add,1);
    for(i=0;i<num;i++)
    {
     lcd_write_data(s[i]);
    }
    break;
    //------------------------------------------------------------------------------
   case 1:
    lcd_write_command(0x80+0x40+add,1);
    for(i=0;i<num;i++)
    {
     lcd_write_data(s[i]);
    }
    break;
  default:
    break;
  }
}

.h文件不用发了~~肯定会~~

然后就是

Delay.c

//------------------------------------------------------------------------------
//测试软件延时和写位运算的~~
#include"lpc210x.h"
#include"macroandconst.h"
//------------------------------------------------------------------------------
#define xtal 12       //晶振的频率,单位MHz,是可以改变的~~
//------------------------------------------------------------------------------
//延时1ms函数
void delay_1ms()
{
 uint32 i;
 for(i=1;i<(uint32)(xtal*143-2);i++)
 
}
//------------------------------------------------------------------------------
//延时nms函数
void delay_nms(uint32 n)
{
 uint32 i=0;
 while(i<n)
 {
  delay_1ms();
  i++;
 
}

顺便把位操作的问价发一下吧~~

感觉还是挺有用的~~

bit.h

#ifndef __bit_h
#define __bit_h
//------------------------------------------------------------------------------
#include"lpc210x.h"
//------------------------------------------------------------------------------
#define CPL_BIT(x,y)  (x^=(1<<y))        //取反某一位
#define CLR_BIT(x,y)  (x&=~(1<<y))       //清零某一位
#define SET_BIT(x,y)  (x|=(1<<y))        //置位某一位
#define GET_BIT(x,y)  (x&(1<<y))         //判断某一位是否为0
#endif

单片机

每天更新
单片机
各种知识,电子制作DIY,及
电子行业
最新资讯,关注我们,棒棒哒!

我在上大学时也学习的51单片机,当时授课老师在教授这门课程的时候是基本脱离硬件的,以汇编编程为主,主要讲111条汇编指令,一堂课讲4条,当时跟听天书一样完全听不懂。这个汇编课件是老师积累了多年所形成的教案,汇编的指令清晰,教案的结构容易把控,课时容易规划,所以课件不会轻易改动,即使老师不用汇编编程。

生成海报
点赞 0

Abin

我还没有学会写个人说明!

相关推荐

W806开发板环境搭建

W806开发板环境搭建 一、芯片介绍 W806是联盛德全新推出的安全 IoT MCU 芯片,支持平头哥CDK开发环境,芯片大小 6×6mm ,芯片集成 32 位 CPU 处理器,内置

STM32 4*4矩阵键盘实现原理(附程序)

STM32 4*4矩阵键盘实现原理(附程序) : 理解矩阵键盘之前,先要了解一下独立按键的触发原理。下图是普通独立 按键的接线图。 : 按键的一端接地,一端接MCU的GPIO。当按键