OpenEdv-开源电子网

 找回密码
 立即注册
正点原子全套STM32/Linux/FPGA开发资料,上千讲STM32视频教程免费下载...
查看: 5183|回复: 5

原子哥我的问题功能和代码都完整交代清楚了麻烦你帮帮忙

[复制链接]

51

主题

340

帖子

0

精华

论坛元老

Rank: 8Rank: 8

积分
3275
金钱
3275
注册时间
2013-9-21
在线时间
281 小时
发表于 2014-4-10 19:19:19 | 显示全部楼层 |阅读模式
这是一个数码管绍数板子
要完成的功能是倒数99秒可以8段分别调整计时同时也可以随时记忆
现在遇到的问题是1-8段中调整第六段的值~第七段就会被同步变动一样的值
但1-6和第8段却是正常可以记忆的
24C02也换过很多各了
很奇怪为什么刚好在中间第七段无法记忆且会随着第六段调整时同步被调整
要麻烦原子哥协助修改
以下是主程序代码其他付程序都是用原子哥的
#include "stm32f10x.h"
#include "sys.h"
#include "delay.h"
#include "24cxx.h"
/*------------------------------------------------------------
                           端口定义
------------------------------------------------------------*/
#define LATCH1 (1<<8)//
#define LATCH2 (1<<9)//
        
                                        
#define LATCH1_SET(x) GPIOB->ODR=(GPIOB->ODR&~LATCH1)|(x ? LATCH1:0)
#define LATCH2_SET(x) GPIOB->ODR=(GPIOB->ODR&~LATCH2)|(x ? LATCH2:0)                                                       
#define DataPort(x)   GPIOA->ODR=(GPIOA->ODR&0xffffff00)|(x&0xff);//定义8位数据操作端口

#define KEY0  GPIO_ReadInputDataBit(GPIOB,GPIO_Pin_11)//读取启动按键
#define KEY1  GPIO_ReadInputDataBit(GPIOB,GPIO_Pin_12)//读取按键1-秒数增加钮
#define KEY2  GPIO_ReadInputDataBit(GPIOB,GPIO_Pin_13)//读取按键2-秒数减少钮
#define KEY3  GPIO_ReadInputDataBit(GPIOB,GPIO_Pin_14)//读取按键3-9段增加钮
#define KEY4  GPIO_ReadInputDataBit(GPIOB,GPIO_Pin_15)//读取按键4-9段减少钮
   
unsigned char const dofly_DuanMa[]={0x3f,0x06,0x5b,0x4f,0x66,0x6d,0x7d,0x07,0x7f,0x6f};
//
unsigned char const dofly_WeiMa[]={0xfe,0xfd,0xfb,0xf7,0xef,0xdf,0xbf,0x7f};
//
unsigned char Duan[10]={0,0,0,0,0,0,0,0,0,0};//9段倒数阵列中的变数-全部初始化为0防止读取到的值会乱码
unsigned char TempData[8]; //存储显示值的全局变量
void Display(unsigned char FirstBit,unsigned char Num);
void KEY(void);//将所有按钮功能的函数代码都包含在这里面方便主程序调用

void TIM3_Int_Init(u16 arr,u16 psc);//通用定时器3初始化
unsigned char num=0;//number简称num数字的意思这里为全域变数是倒数秒的值-初始化为0秒
unsigned char k=1;//k为9段倒数的阵列中循环用变数-初始化为1
/*------------------------------------------------
                    主函数
------------------------------------------------*/
int main()
{

    GPIO_InitTypeDef GPIO_InitStructure;
    RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOA | RCC_APB2Periph_GPIOB , ENABLE);     //使能GPIOA-B-C时钟           
    GPIO_InitStructure.GPIO_Pin   = GPIO_Pin_All;//选择全部A-PORT脚位
    GPIO_InitStructure.GPIO_Speed = GPIO_Speed_2MHz;//IO口速度为最低2M
    GPIO_InitStructure.GPIO_Mode  = GPIO_Mode_Out_PP;//推挽输出
    GPIO_Init(GPIOA, &GPIO_InitStructure);//初始化GPIOA
   
  GPIO_InitStructure.GPIO_Pin   = GPIO_Pin_8|GPIO_Pin_9|GPIO_Pin_10;//Pin8-Pin9控制74HC573位码-段码Pin10控制蜂鸣器低电位不要发声
    GPIO_InitStructure.GPIO_Speed = GPIO_Speed_2MHz;
    GPIO_InitStructure.GPIO_Mode  = GPIO_Mode_Out_PP;
    GPIO_Init(GPIOB, &GPIO_InitStructure);//初始化GPIOB
  GPIO_ResetBits(GPIOB,GPIO_Pin_10);//将GPIOB的Pin-10脚    设定为高电位
   
    GPIO_InitStructure.GPIO_Pin  = GPIO_Pin_11|GPIO_Pin_12|GPIO_Pin_13|GPIO_Pin_14|GPIO_Pin_15;//控制KEY
    GPIO_InitStructure.GPIO_Mode = GPIO_Mode_IPU; //设置成上拉输入
     GPIO_Init(GPIOB, &GPIO_InitStructure);//初始化GPIOB11-12
   
 
   
  AFIO->MAPR = (0x00FFFFFF & AFIO->MAPR)|0x04000000;          //关闭JTAG

    delay_init();    //STM32专用的延时函数
    AT24CXX_Init();
    NVIC_Configuration();//中断优先权库函数      
    TIM3_Int_Init(9,719);//定时器3初始化赋于值((9+1)*(719+1)/72=100单位us)
        AT24CXX_Read(0,(u8*)Duan,12);
        num=Duan[k];
 while(1)//主循环
  {   
        KEY();//调用KEY按钮所有库函数                     
     }
}

void Display(unsigned char FirstBit,unsigned char Num)
{
      unsigned char i;
     
      for(i=0;i<Num;i++)
       {
       DataPort(0);   //清空数据,防止有交替重影
       LATCH1_SET(1);     //段锁存
       LATCH1_SET(0);

       DataPort(dofly_WeiMa[i+FirstBit]); //个位数码
       LATCH2_SET(1);     //锁存
       LATCH2_SET(0);

       DataPort(TempData); //段码
       LATCH1_SET(1);     //锁存
       LATCH1_SET(0);
             
             delay_us(20);//调整数码管十位数的明暗度(太高会造成显示不跳动)
      }
}
//通用定时器3中断初始化
//这里时钟选择为APB1的2倍,而APB1为36M
//arr:自动重装值。
//psc:时钟预分频数
//这里使用的是定时器3!
void TIM3_Int_Init(u16 arr,u16 psc)
{
    TIM_TimeBaseInitTypeDef  TIM_TimeBaseStructure;
    NVIC_InitTypeDef NVIC_InitStructure;

    RCC_APB1PeriphClockCmd(RCC_APB1Periph_TIM3, ENABLE); //时钟使能
   
   
    TIM_TimeBaseStructure.TIM_Period = arr; //设置在下一个更新事件装入活动的自动重装载寄存器周期的值
    TIM_TimeBaseStructure.TIM_Prescaler =psc; //设置用来作为TIMx时钟频率除数的预分频值
    TIM_TimeBaseStructure.TIM_ClockDivision = TIM_CKD_DIV1; //设置时钟分割:TDTS = Tck_tim
    TIM_TimeBaseStructure.TIM_CounterMode = TIM_CounterMode_Up;  //TIM向上计数模式
    TIM_TimeBaseInit(TIM3, &TIM_TimeBaseStructure); //根据指定的参数初始化TIMx的时间基数单位
 
    TIM_ITConfig(TIM3,TIM_IT_Update,ENABLE ); //使能指定的TIM3中断,允许更新中断

    //中断优先级NVIC设置
    NVIC_InitStructure.NVIC_IRQChannel = TIM3_IRQn;  //TIM3中断
    NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = 0; //先占优先级0级
    NVIC_InitStructure.NVIC_IRQChannelSubPriority = 3;  //从优先级3级
    NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE; //IRQ通道被使能
    NVIC_Init(&NVIC_InitStructure);  //初始化NVIC寄存器


    TIM_Cmd(TIM3, ENABLE);  //使能TIMx                 
}
//定时器3中断服务程序
void TIM3_IRQHandler(void)   //TIM3中断
{
   
    if (TIM_GetITStatus(TIM3, TIM_IT_Update) != RESET)  //检查TIM3更新中断发生与否
        {
        TIM_ClearITPendingBit(TIM3, TIM_IT_Update  );  //清除TIMx更新中断标志
        TempData[0]=dofly_DuanMa[num/10];//倒数秒数十位数                     
        TempData[1]=dofly_DuanMa[num%10];//倒数秒数个位数-使用定时器来扫描数码管
            TempData[2]=dofly_DuanMa[k]; //9段倒数用显示段数
            Display(2,3);//2代表0-1-2从第三位数开始显示,3代表共计数三个位数
        }
}

void KEY(void)
{
unsigned int key_press_num;//区域变数用于区分长按跟短按变数
unsigned int i=0; //区域变数-倒数累加变数
unsigned int j=0;    //区域变数-长时间按钮累加用变数
   
   
        if(KEY0==0)//如果检测到低电平,说明[启动按键]按下
         {
             k=1;//当启动按钮按下后先将段数值k=1
             num=Duan[k];//将9段倒数阵列移入显示秒num值中-将段数阵列值移入秒值进行倒数运算并同时等同控制显示变数来显示变化   
      while(1)
       {
                 i++;
          if(i==1100000) //循环累加构成延时来启动倒数累减的功能
                    {
                    i=0;
                if(num>0)//用于显示0~99
                        {
                    num--;                                                     
                      }           
                         if(num==0)//当秒值倒数为0时
                         {
                            k++;
                            num=Duan[k];//将段数阵列值移入秒值进行倒数运算并同时等同控制显示变数来显示变化   
                            if(k>8)                   
                             {
                                 k=1;
                                 num=Duan[k];//将段数阵列值移入秒值进行倒数运算并同时等同控制显示变数来显示变化必须在倒数值为0时才可给回归指令   
                             break;//此处是为了让while无尽循环达到标准来退回主循环中
                             }                                 
                         }                           
                  }   
                }   
            }               
                                                        
               
  if(!KEY1)
    {
     delay_us(600); //延时去抖,一般600us为了防止按键弹跳太快
     if(!KEY1)    
       {
             delay_us(300); //延时去抖,一般300us
       while(!KEY1) //再次确认按键是否按下,没有按下则退
        {
        key_press_num++;
        delay_ms(1);           
        if(key_press_num==10000) //循环累加构成延时来启动长按钮
          {
           key_press_num=0;    
                              
           while(!KEY1) //这里用于识别是否按键还在按下,如果按下执行相关动作,否则退出   
               {
                         j++;
                         if(j==30000) //如果达到长按键标准则进入长按键动作
                         {
                             j=0;
                   if(num<99)   //长按钮的累加操作
                  num++;
                      TempData[0]=dofly_DuanMa[num/10];
                TempData[1]=dofly_DuanMa[num%10];//分解显示信息,如要显示68,则68/10=6  68%10=8
              delay_us(200); //用于调节长按循环操作的速度,可以自行调整此值以便达到最佳效果
                    }
                }
            }
          }
      key_press_num=0;
           if(num<99)   //累加操作
              num++;
       }
    }

 if(!KEY2)
    {
     delay_us(600); //延时去抖,一般600us
     if(!KEY2)
       {
             delay_us(300); //延时去抖,一般300us
       while(!KEY2) //再次确认按键是否按下,没有按下则退
        {
        key_press_num++;
        delay_ms(1);
        if(key_press_num==8000) //循环累加构成延时来启动长按钮
          {
           key_press_num=0;
           while(!KEY2)  //这里用于识别是否按键还在按下,如果按下执行相关动作,否则退出
               {
                              j++;
                         if(j==30000) //如果达到长按键标准则进入长按键动作
                         {
                             j=0;
                   if(num>0)  //长按钮的累减操作
                   num--;
                      TempData[0]=dofly_DuanMa[num/10];
                TempData[1]=dofly_DuanMa[num%10];//分解显示信息,如要显示68,则68/10=6  68%10=8
              delay_us(200); //用于调节长按循环操作的速度,可以自行调整此值以便达到最佳效果
                }
            }
            }
        }
      key_press_num=0;
           if(num>0)  //累减操作
              num--;

       }
    }   
   
    switch(k) //开关指令用来区分k值1-8分别代表阵列中9个变数-9个变数分别存放9段倒数秒数值
    {
        case 1:
        Duan[1]=num;//将num阵列暂存区的值转9段阵列值-当k=1时代表第一段倒数秒数值
        AT24CXX_Write(0,(u8*)Duan,12);
        break;
        case 2:
        Duan[2]=num;
        AT24CXX_Write(0,(u8*)Duan,12);
        break;
        case 3:
        Duan[3]=num;
        AT24CXX_Write(0,(u8*)Duan,12);
        break;
        case 4:
        Duan[4]=num;
        AT24CXX_Write(0,(u8*)Duan,12);
        break;
        case 5:
        Duan[5]=num;
        AT24CXX_Write(0,(u8*)Duan,12);
        break;
        case 6:
        Duan[6]=num;
        AT24CXX_Write(0,(u8*)Duan,12);
        case 7:
        Duan[7]=num;
        AT24CXX_Write(0,(u8*)Duan,12);
        break;
        case 8:
        Duan[8]=num;
        AT24CXX_Write(0,(u8*)Duan,12);
        break;

    }
    //此处按钮定义为9段k变数上调功能
if(!KEY3)  //如果检测到低电平,说明按键按下
    {
     delay_us(500); //延时去抖,一般10-20ms
     if(!KEY3)     //再次确认按键是否按下,没有按下则退出
       {
        while(!KEY3);//如果确认按下按键等待按键释放,没有释放则一直等待
           {
                     k++;//加操作
                     num=Duan[k];//强调在将9段倒数阵列值移回num-因为显示变数为num这样才看得到调整段数在移动的样子                     
           if(k>8)  //当段数大于8则循环到1
             k=1;
                   num=Duan[k];//强调在将9段倒数阵列值移回num-因为显示变数为num这样才看得到调整段数在移动的样子
             }
       }
    }

//此处按钮定义为9段k变数下调功能
if(!KEY4)  //如果检测到低电平,说明按键按下
    {
     delay_us(500); //延时去抖,一般10-20ms
     if(!KEY4)     //再次确认按键是否按下,没有按下则退出
       {
        while(!KEY4);//如果确认按下按键等待按键释放,没有释放则一直等待
           {
                     k--;//减操作
                  num=Duan[k];//强调在将9段倒数阵列值移回num-因为显示变数为num这样才看得到调整段数在移动的样子
           if(k<1)  //当段数少于1则循环到8
              k=8;
                 num=Duan[k];//强调在将9段倒数阵列值移回num-因为显示变数为num这样才看得到调整段数在移动的样子
             }
       }
    }
}
 
正点原子逻辑分析仪DL16劲爆上市
回复

使用道具 举报

530

主题

11万

帖子

34

精华

管理员

Rank: 12Rank: 12Rank: 12

积分
165475
金钱
165475
注册时间
2010-12-1
在线时间
2115 小时
发表于 2014-4-10 23:10:29 | 显示全部楼层
改成这样:
    switch(k) //开关指令用来区分k值1-8分别代表阵列中9个变数-9个变数分别存放9段倒数秒数值
    {
        case 1:
        Duan[1]=num;//将num阵列暂存区的值转9段阵列值-当k=1时代表第一段倒数秒数值
   
        AT24CXX_Write(0,(u8*)Duan,12);
printf("k1:%d\r\n",k);
        break;
        case 2:
        Duan[2]=num;
        AT24CXX_Write(0,(u8*)Duan,12); 
printf("k2:%d\r\n",k);
        break;
        case 3:
        Duan[3]=num;
        AT24CXX_Write(0,(u8*)Duan,12);
printf("k3:%d\r\n",k);
        break;
        case 4:
        Duan[4]=num;
        AT24CXX_Write(0,(u8*)Duan,12);
printf("k4:%d\r\n",k);
        break;
        case 5:
        Duan[5]=num;
        AT24CXX_Write(0,(u8*)Duan,12);
printf("k5:%d\r\n",k);
        break;
        case 6:
        Duan[6]=num;
        AT24CXX_Write(0,(u8*)Duan,12);
printf("k6:%d\r\n",k);
        case 7:
        Duan[7]=num;
        AT24CXX_Write(0,(u8*)Duan,12); 
printf("k7:%d\r\n",k);
        break;
        case 8:
        Duan[8]=num;
        AT24CXX_Write(0,(u8*)Duan,12); 
printf("k8:%d\r\n",k);
        break;

    }

测试下你的k1~k8是否都有打印出来?
我是开源电子网www.openedv.com站长,有关站务问题请与我联系。
正点原子STM32开发板购买店铺http://openedv.taobao.com
正点原子官方微信公众平台,点击这里关注“正点原子”
回复 支持 反对

使用道具 举报

28

主题

1489

帖子

0

精华

论坛大神

Rank: 7Rank: 7Rank: 7

积分
1656
金钱
1656
注册时间
2013-7-24
在线时间
1 小时
发表于 2014-4-10 23:22:08 | 显示全部楼层
注释好多,过犹不及啊。
于20150522停用该账号:http://www.microstar.club
回复 支持 反对

使用道具 举报

51

主题

340

帖子

0

精华

论坛元老

Rank: 8Rank: 8

积分
3275
金钱
3275
注册时间
2013-9-21
在线时间
281 小时
 楼主| 发表于 2014-4-11 06:12:23 | 显示全部楼层
回复【2楼】正点原子:
---------------------------------
我现在刚好怀疑K7没有执行到?
回复 支持 反对

使用道具 举报

51

主题

340

帖子

0

精华

论坛元老

Rank: 8Rank: 8

积分
3275
金钱
3275
注册时间
2013-9-21
在线时间
281 小时
 楼主| 发表于 2014-4-11 06:14:19 | 显示全部楼层
回复【2楼】正点原子:
---------------------------------
一样可以用数码管打印?
我直接修改就可以用了?
回复 支持 反对

使用道具 举报

530

主题

11万

帖子

34

精华

管理员

Rank: 12Rank: 12Rank: 12

积分
165475
金钱
165475
注册时间
2010-12-1
在线时间
2115 小时
发表于 2014-4-12 01:07:21 | 显示全部楼层
回复【5楼】hack906447:
---------------------------------
printf是输出到串口的,和数码管无关哦。
我是开源电子网www.openedv.com站长,有关站务问题请与我联系。
正点原子STM32开发板购买店铺http://openedv.taobao.com
正点原子官方微信公众平台,点击这里关注“正点原子”
回复 支持 反对

使用道具 举报

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

本版积分规则



关闭

原子哥极力推荐上一条 /2 下一条

正点原子公众号

QQ|手机版|OpenEdv-开源电子网 ( 粤ICP备12000418号-1 )

GMT+8, 2025-5-12 14:30

Powered by OpenEdv-开源电子网

© 2001-2030 OpenEdv-开源电子网

快速回复 返回顶部 返回列表