STM32 控制74HC595 驱动点阵 文字能移动

发布者:平静的33号最新更新时间:2018-05-30 来源: eefocus关键字:STM32  控制74HC595  驱动点阵 手机看文章 扫描二维码
随时随地手机看文章

遇到了很奇怪的问题,程序明明没错但就是不显示,最后把在main函数中定义的变量count移动到main 外面就正常了 。仿真后发现,在main 函数中定义的局部变量 初始值不为0 ,超出控制范围 , 导致程序跑飞。按理说keil 定义变量默认初始化为0才对 。最后将定义count初始化为0,程序正常运行。下次定义变量一定要初始化啊!!!

在单步调试中,发现这个问题。不得不说一下,keil 在线仿真非常好用。

#include  

#include  

  

  

void spi2Init(void);  

void gpioInit(void);  

void delay(unsigned int i);  

  

void DisplayOnLattice(unsigned char a,unsigned char b,unsigned char c,unsigned char d );  

  

unsigned char table[]={0x80,0x00,0x40,0x00,0x20,0x00,0x10,0x00,0x08,0x00,0x04,0x00,0x02,0x00,0x01,0x00,0x00,0x80,0x00,0x40,0x00,0x20,0x00,0x10,0x00,0x08,0x00,0x04,0x00,0x02,0x00,0x01};  

  

static unsigned char bb[]={0x01,0x00,0x01,0x00,0x01,0xF0,0x1F,0x80,0x05,0x40,0x09,0x30,0x11,0xCE,0x26,0x40,  

0x00,0x80,0x01,0xFC,0x7F,0x00,0x00,0x80,0x00,0x80,0x02,0x80,0x01,0x00,0x00,0x00};  

[cpp] view plain copy

//static unsigned char aa[]={0x80,0x00,0x40,0x00,0x20,0x00,0x10,0x00,0x08,0x00,0x04,0x00,0x02,0x00,0x01,0x00,0x00,0x80,0x00,0x40,0x00,0x20,0x00,0x10,0x00,0x08,0x00,0x04,0x00,0x02,0x00,0x01};  

  

static unsigned char cc[]={0x01,0xC0,0x07,0x00,0x01,0xF8,0x1F,0x08,0x21,0x40,0x29,0x00,0x01,0x60,0x0C,0x20,  

0x14,0xC0,0x1C,0x60,0x11,0xA0,0x1C,0x40,0x10,0xA0,0x1B,0x18,0x10,0x0E,0x00,0x00};  

unsigned char dd[]={0};  

unsigned char *pointer[]={bb,cc};  

/* 在这里 用到了指针数组pointer ,*(pointer[0])指向数组bb的首个元素地址 

    *(pointer[1])指向数组cc的首个元素地址 

    上面字库定义时 bb和cc两个数组是连在一起的,所以下面可以连续滚动多个字 

    unsigned char *pointer[]={bb,cc};也可以定义成unsigned char *pointer[]={bb}; 

    程序也能正常运行。                                                    

    若把定义aa数组的注释去掉,则程序将不能显示连续滚动连续的两个汉字的功能:                                            

    */  

  

  

  

   

int main()  

{  

  

  unsigned char i=0,count=0; //count 没有初始化导致错误  

  unsigned int time=0;  

  

  gpioInit();  

    spi2Init();  

  

    while(1)  

    {  

      

        for(time=0;time<1000;time++)        //不行  

        for(i=0;i<32;i+=2)  

        DisplayOnLattice(~(*(pointer[0]+i+1+count)),~(*(pointer[0]+i+count)),table[i+1],table[i]);    

        count+=2;  

        if(count==17*2)  

        count=0;   

          

  

    }  

      

      

}  

  

  

  

  

void DisplayOnLattice(unsigned char a,unsigned char b,unsigned char c,unsigned char d )  

{  

    GPIO_WriteBit(GPIOB,GPIO_Pin_12,Bit_RESET);  

      

    SPI_I2S_SendData(SPI2,a);  

    while(SPI_I2S_GetFlagStatus(SPI2,SPI_I2S_FLAG_TXE)==0);  

    SPI_I2S_ClearFlag(SPI2,SPI_I2S_FLAG_TXE);  

      

    SPI_I2S_SendData(SPI2,b);  

    while(SPI_I2S_GetFlagStatus(SPI2,SPI_I2S_FLAG_TXE)==0);  

    SPI_I2S_ClearFlag(SPI2,SPI_I2S_FLAG_TXE);  

      

    SPI_I2S_SendData(SPI2,c);  

    while(SPI_I2S_GetFlagStatus(SPI2,SPI_I2S_FLAG_TXE)==0);  

    SPI_I2S_ClearFlag(SPI2,SPI_I2S_FLAG_TXE);  

      

    SPI_I2S_SendData(SPI2,d);  

    while(SPI_I2S_GetFlagStatus(SPI2,SPI_I2S_FLAG_TXE)==0);  

    SPI_I2S_ClearFlag(SPI2,SPI_I2S_FLAG_TXE);  

    delay(1);  

    GPIO_WriteBit(GPIOB,GPIO_Pin_12,Bit_SET);  

      

  

    GPIO_WriteBit(GPIOB,GPIO_Pin_12,Bit_RESET);  

  

}  

  

void spi2Init()  

{  

    SPI_InitTypeDef SPI_InitStructure;  

      

      

    RCC_APB1PeriphClockCmd(RCC_APB1Periph_SPI2, ENABLE);  

      

  SPI_InitStructure.SPI_Direction = SPI_Direction_2Lines_FullDuplex;  

  SPI_InitStructure.SPI_Mode = SPI_Mode_Master;  

  SPI_InitStructure.SPI_DataSize = SPI_DataSize_8b;  

  SPI_InitStructure.SPI_CPOL = SPI_CPOL_High ;  

  SPI_InitStructure.SPI_CPHA = SPI_CPHA_2Edge;  

  SPI_InitStructure.SPI_NSS = SPI_NSS_Soft;  

  SPI_InitStructure.SPI_BaudRatePrescaler = SPI_BaudRatePrescaler_4;  

  SPI_InitStructure.SPI_FirstBit = SPI_FirstBit_LSB;    //most significant bit 最高有效位 看具体取模方式  

  SPI_InitStructure.SPI_CRCPolynomial = 0;  

  SPI_Init(SPI2, &SPI_InitStructure);  

    SPI_Cmd(SPI2, ENABLE);  

}  

  

void gpioInit(void)  

{  

    GPIO_InitTypeDef gpio;  

    RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOB , ENABLE);  

      

    gpio.GPIO_Pin=GPIO_Pin_12;             //CS   作为74hc595 RCLK  并行输出 上升沿有效  

    gpio.GPIO_Speed=GPIO_Speed_50MHz;  

    gpio.GPIO_Mode = GPIO_Mode_Out_PP;  

    GPIO_Init(GPIOB, &gpio);  

      

    gpio.GPIO_Pin=GPIO_Pin_13;              //SCK   作为74hc595 SRCLK  串行输入时钟  

    gpio.GPIO_Speed=GPIO_Speed_50MHz;  

    gpio.GPIO_Mode = GPIO_Mode_AF_PP;  

    GPIO_Init(GPIOB, &gpio);  

      

    gpio.GPIO_Pin=GPIO_Pin_14;             //MISO 空闲  

    gpio.GPIO_Speed=GPIO_Speed_50MHz;  

    gpio.GPIO_Mode = GPIO_Mode_AF_PP;  

    GPIO_Init(GPIOB, &gpio);  

      

    gpio.GPIO_Pin=GPIO_Pin_15;              //MOSI 作为74hc595 DATA线  

    gpio.GPIO_Speed=GPIO_Speed_50MHz;  

    gpio.GPIO_Mode = GPIO_Mode_AF_PP;  

    GPIO_Init(GPIOB, &gpio);  

  

  

}  

  

void delay(unsigned int i)  

{  

    int j;  

    for(j=0;j<1000;j++)  

    for(;i>0; i--);  

}  


关键字:STM32  控制74HC595  驱动点阵 引用地址:STM32 控制74HC595 驱动点阵 文字能移动

上一篇:STM32事件 中断事件 中断的详解
下一篇:STM32+74HC595:带领你10分钟用对74HC595

推荐阅读最新更新时间:2024-03-16 16:03

使用STM32的systick定时器中断实现RTC工作过程出错
开发环境:keil MDK V5.10 操作系统:windows 7(32位) 目标硬件:STM32F103C8 问题描述:使用STM32的systick定时器实现RTC功能。具体方法为systick滴答计时器配置为1ms时间间隔的滴答中断,定义一个RTC结构体,包含年、月、日、时、分、秒。在每进一次systick中断服务程序中更新一次RTC的值。主程序通过不停地获取RTC的时钟,每一秒钟使用printf函数输出当前的时间。测试过程发现绝大多数时间系统正常工作,但依然存在部分情况系统无法进行正常的输出。相关代码和测试结果如下: /** * @brief 系统滴答定时器中断服务程序,主要功能为更新实时时钟 *
[单片机]
STM32(六)外部中断-EXTI
一、外部中断叙述 1、STM32的每个IO都可以作为外部中断输入。 2、STM32的中断控制器支持19个外部中断/事件请求: 线0~15:对应外部IO口的输入中断。 线16:连接到PVD输出。 线17:连接到RTC闹钟事件。 线18:连接到USB唤醒事件。 3、每个外部中断线可以独立的配置触发方式(上升沿,下降沿或者双边沿触发),触发/屏蔽,专用的状态位。 从上面可以看出,STM32供IO使用的中断线只有16个,但是STM32F10x系列的IO口多达上百个,STM32F103ZET6(112), STM32F103RCT6(51),那么中断线怎么跟io口对应呢? GPIOx.0映射到EXTI0 GPIOx.1映
[单片机]
<font color='red'>STM32</font>(六)外部中断-EXTI
STM32串口通信的原理
通信接口背景知识 设备之间通信的方式 一般情况下,设备之间的通信方式可以分成并行通信和串行通信两种。并行与串行通信的区别如下表所示。 串行通信的分类 1、按照数据传送方向,分为: 单工:数据传输只支持数据在一个方向上传输; 半双工:允许数据在两个方向上传输。但是,在某一时刻,只允许数据在一个方向上传输,它实际上是一种切换方向的单工通信;它不需要独立的接收端和发送端,两者可以合并一起使用一个端口。 全双工:允许数据同时在两个方向上传输。因此,全双工通信是两个单工通信方式的结合,需要独立的接收端和发送端。 2、按照通信方式,分为: 同步通信:带时钟同步信号传输。比如:SPI,IIC通信接口。 异步通信:不带时钟同步信号
[单片机]
<font color='red'>STM32</font>串口通信的原理
STM32实验2:IO输入
端口初始化 #include stm32f10x.h //PA15void KEY_Init(void) { GPIO_InitTypeDef GPIO_InitStructure; RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOA,ENABLE);//使能外设置时钟 GPIO_InitStructure.GPIO_Pin = GPIO_Pin_15; //PA15上拉输入 GPIO_InitStructure.GPIO_Mode = GPIO_Mode_IPU; GPIO_Init(GPIOA, &GPIO_InitStructure); }1234567891011
[单片机]
STM32以太网程序解析二
--------------------------------------------------------------------------------------------------------------------------- 下面我们来详细看一下程序,我们将逐行的进行分析。 1. int simple_server(void) 2. { 3. unsigned int plen,dat_p,i1=0,payloadlen=0; 4. unsigned char i=0,*buf1 = 0; 5. signed char cmd; 6. 7. /
[单片机]
STM32开发 -- Keil使用(1)
一、keil主界面详解 打开一个工程文件,可以看到如下的界面: 下面我们就一一来介绍下。为了讲解专门找到一个keil汉化补丁。也是够够的了。 这里的汉化为了方便讲解,实际工作中建议还是用英文版本。 下载:keil 4汉化包 1、菜单栏 文件 其中需要注意的是 License Management,破解时需要在这里输入。 编辑 视图 工程 闪存 调试 外围设备(仿真) 工具 2、工具栏 文件操作 新建文件夹 Ctrl + N 打开文件 Ctrl + O 保存当前文件 Ctrl + S 保存所有文件 无 剪切 Ctrl + X 复制 Ctrl + C 粘贴 Ctrl + V
[单片机]
<font color='red'>STM32</font>开发 -- Keil使用(1)
stm32如何获取自己的ID号
一、函数。 void STM32_GetChipID(unsigned int *cID) { cID =*(vu32*)(0x1ffff7e8); cID =*(vu32*)(0x1ffff7ec); cID =*(vu32*)(0x1ffff7f0); } 二、可以用串口打印出来。 Printf( \r\nChip ID: %d, %d, %d\r\n , cID , cID , cID );
[单片机]
STM32的嵌套中断系统NVIC和RCC详细整理
STM32的嵌套中断系统NVIC和RCC详细整理 用的是stm32f103的最新3.5的库。 一、综述: 1、STM32 (Cortex-M3) 中的优先级概念 STM32(Cortex-M3)中有两个优先级的概念:抢占式优先级和响应优先级,也把响应优先级称作 亚优先级 或 副优先级 ,每个中断源都需要被指定这两种优先级。 1. 何为占先式优先级(pre-emption priority) 高占先式优先级的中断事件会打断当前的主程序/中断程序运行 抢断式优先响应,俗称中断嵌套。 2. 何为副优先级(subpriority) 在占先式优先级相同的情况下,高副优先级的中断优先被响应; 在占先式优先级相同
[单片机]
小广播
添点儿料...
无论热点新闻、行业分析、技术干货……
设计资源 培训 开发板 精华推荐

最新单片机文章
何立民专栏 单片机及嵌入式宝典

北京航空航天大学教授,20余年来致力于单片机与嵌入式系统推广工作。

换一换 更多 相关热搜器件
随便看看
电子工程世界版权所有 京B2-20211791 京ICP备10001474号-1 电信业务审批[2006]字第258号函 京公网安备 11010802033920号 Copyright © 2005-2024 EEWORLD.com.cn, Inc. All rights reserved