这些小活动你都参加了吗?快来围观一下吧!>>
电子产品世界 » 论坛首页 » 高校专区 » 漓东e学堂 » 为什么我的中断函数执行完后没有继续执行主函数的内容?(以串口控制LED为例)

共13条 1/2 1 2 跳转至

为什么我的中断函数执行完后没有继续执行主函数的内容?(以串口控制LED为例)

菜鸟
2014-11-09 16:26:38     打赏


前期工作在“16号同学的作业本”,链接在此:

http://forum.eepw.com.cn/thread/260879/5/#43


任务目标:

   在串口调试助手向STM32发送数据,控制LED流水等循环闪烁的速率。

发送格式:

   data=n 即相邻两个LED的闪烁间隔为n毫秒,n的范围是1~9999。

完成进度:

   led1~led8的初始状态为循环闪烁,一边闪烁一边等待中断;

   通过串口发送data=n,使相邻的两个LED闪烁间隔为n毫秒,以此速率8个LED循环闪烁3轮后又全部熄灭,等待下一次发送的新数据。

疑难:

1.主函数以一个while(1)的循环,一边循环点亮led1~led8,一边等待中断,但是第一次的中断函数执行完以后(即led1~led8以n毫秒为间隔时间闪烁3轮),程序没有继续回到主函数的while(1)循环点亮led1~led8,这是为什么?

2.我目前只能让流水灯循环闪烁有限次,完成有限次的循环后,才能执行新来的中断。有没有办法让led闪烁速率保持在n毫秒的状态下接收新的中断,再保持新的闪烁速率……以此循环 ?


视频地址:http://player.youku.com/player.php/sid/XODIzMDY2MDMy/v.swf

代码如下:

#include "stm32f10x.h"
#include "stm32_eval.h"
#include	"stdio.h"
#include "math.h"
#define buff_size  16;     
char rx_buff[], rx_buff_count=0;
//static unsigned int sum;//静态局部变量sum
GPIO_InitTypeDef  GPIO_InitStructure;
USART_InitTypeDef  USART_InitStructure;
NVIC_InitTypeDef  NVIC_InitStructure;
USART_ClockInitTypeDef  USART_ClockInitStructure;

void RCC_Configuration(void)
{
	RCC_DeInit();
	RCC_HSICmd(ENABLE);
	while(RCC_GetFlagStatus(RCC_FLAG_HSIRDY) == RESET);
	RCC_SYSCLKConfig(RCC_SYSCLKSource_HSI);
	RCC_HSEConfig(RCC_HSE_OFF);
	RCC_LSEConfig(RCC_LSE_OFF);
	RCC_PLLConfig(RCC_PLLSource_HSI_Div2,RCC_PLLMul_9); //  72HMz
	RCC_PLLCmd(ENABLE);
	while(RCC_GetFlagStatus(RCC_FLAG_PLLRDY) == RESET);
	RCC_ADCCLKConfig(RCC_PCLK2_Div4);
	RCC_PCLK2Config(RCC_HCLK_Div1);
	RCC_PCLK1Config(RCC_HCLK_Div2);
	RCC_HCLKConfig(RCC_SYSCLK_Div1);
	RCC_SYSCLKConfig(RCC_SYSCLKSource_PLLCLK);
	while(RCC_GetSYSCLKSource() != 0x08);
	RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOD|RCC_APB2Periph_AFIO, ENABLE);
	GPIO_PinRemapConfig(GPIO_Remap_SWJ_JTAGDisable,ENABLE);//disable JTAG
	GPIO_InitStructure.GPIO_Pin = GPIO_Pin_2;
	GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
	GPIO_InitStructure.GPIO_Mode = GPIO_Mode_Out_PP;
	GPIO_Init(GPIOD, &GPIO_InitStructure);
	GPIO_ResetBits(GPIOD,GPIO_Pin_2);//关闭蜂鸣器
}
void GPIO_INIT()
{
	RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOC, ENABLE);//使能PC时钟

	GPIO_InitStructure.GPIO_Pin = GPIO_Pin_0|GPIO_Pin_1|GPIO_Pin_2|GPIO_Pin_3|GPIO_Pin_4|GPIO_Pin_5|GPIO_Pin_6|GPIO_Pin_7;//PC0-PC7
	GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
	GPIO_InitStructure.GPIO_Mode = GPIO_Mode_Out_PP;//推挽输出 
	GPIO_Init(GPIOC, &GPIO_InitStructure);//初始化PC
}

void USART_int(long BaudRate)
{
	 RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOA|RCC_APB2Periph_USART1,ENABLE);//使能PA USART1
   GPIO_InitStructure.GPIO_Pin = GPIO_Pin_9;//TX位于PA9 
   GPIO_InitStructure.GPIO_Speed = GPIO_Speed_10MHz;
   GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF_PP; //推挽输出
   GPIO_Init(GPIOA, &GPIO_InitStructure);//TX初始化 PA9 
   GPIO_InitStructure.GPIO_Pin = GPIO_Pin_10;//RX位于PA10 
   GPIO_InitStructure.GPIO_Mode = GPIO_Mode_IN_FLOATING;//悬空输入
   GPIO_Init(GPIOA, &GPIO_InitStructure);//RX初始化 PA10 
  /* USARTx configured as follow:
        - BaudRate = 115200 baud  
        - Word Length = 8 Bits
        - One Stop Bit
        - No parity
        - Hardware flow control disabled (RTS and CTS signals)
        - Receive and transmit enabled
  */
	USART_InitStructure.USART_BaudRate = BaudRate;//传输速率
	USART_InitStructure.USART_WordLength = USART_WordLength_8b;//字长8比特
	USART_InitStructure.USART_StopBits = USART_StopBits_1;//停止位1 
	USART_InitStructure.USART_Parity = USART_Parity_No;//
	USART_InitStructure.USART_HardwareFlowControl = USART_HardwareFlowControl_None;//流控位none
	USART_InitStructure.USART_Mode = USART_Mode_Rx | USART_Mode_Tx;//接收和发送模式
	USART_ClockInitStructure.USART_Clock = USART_Clock_Disable;     
  USART_ClockInitStructure.USART_CPOL = USART_CPOL_Low;      
  USART_ClockInitStructure.USART_CPHA = USART_CPHA_2Edge;      
  USART_ClockInitStructure.USART_LastBit = USART_LastBit_Disable;
	USART_ClockInit(USART1, &USART_ClockInitStructure);//初始化USART1时钟
	USART_Init(USART1, &USART_InitStructure);//初始化USART1 
	USART_Cmd(USART1, ENABLE); 
	USART_ITConfig(USART1, USART_IT_RXNE, ENABLE);
	USART_Cmd(USART1, ENABLE);
  /* Configure four bit for preemption priority */
	NVIC_PriorityGroupConfig(NVIC_PriorityGroup_4);//优先级
  /* Enable the USART1 Interrupt */
	NVIC_InitStructure.NVIC_IRQChannel = USART1_IRQn; //选择USART1中断通道
	NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = 15;
	NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE;
	NVIC_Init(&NVIC_InitStructure);//初始化中断
}

/*delay_us*/ 
void delay_us(u32 n)
{
	u8 j;
	while(n--)
	for(j=0;j<10;j++);
}
/*delay_ms*/ 
void  delay_ms(u32 n)
{
	while(n--)
	delay_us(1000);
}

void led_on_2(unsigned int sum)   //led循环闪烁3次
{   
    int i;char j;
    GPIO_SetBits(GPIOC,0x000000ff);
		for(j=0;j<3;j++)
		{
			for(i=0x00000080;i!=0x00000000;)//LED 
			{   
				GPIO_ResetBits(GPIOC,i);//            
				delay_ms(50);   
				GPIO_SetBits(GPIOC,i);// 
				delay_ms(sum); //
				i>>=1;  
			}
		}
}

void USART_SendStr(char *str)//发送字符串
{
   while((*str)!='\0')//到字符串的末尾才停止发送数据
	{	
		USART_SendData(USART1,*str++);
		while(USART_GetFlagStatus(USART1, USART_FLAG_TXE) == RESET);
	}
}

unsigned int translate(char *S,char j)//将字符串组成的数字转换成整型数据
{
	unsigned int a[4],result=0;
	char i;
	for(i=0;i");
}

int main(void)
{ 
	int i=0x00000080;   
	RCC_Configuration();
	GPIO_INIT();
	USART_int(9600);
	USART_SendStr("SyStem booting......\r\n");// 
	USART_SendStr("\n>");// 
  GPIO_SetBits(GPIOC,0x000000ff);//LED
	while(1)//LED循环闪烁
	{   
    GPIO_ResetBits(GPIOC,i);//            
		delay_ms(90);   
		GPIO_SetBits(GPIOC,i);// 
		i>>=1;  
		if(i==0x00000001){i=0x00000080;}
	} 
}

void USART1_IRQHandler(void) 
{ 
  while(USART_GetFlagStatus(USART1, USART_FLAG_RXNE) == RESET)
  {  } 
	if(USART_ReceiveData(USART1)==0x0d)//如果输入完毕,按下了回车
	{input_ASK();}
	else
	{
		USART_SendData(USART1,USART_ReceiveData(USART1));
		rx_buff[rx_buff_count]= USART_ReceiveData(USART1);
		rx_buff_count++;
	}
  	USART_ClearFlag(USART1, USART_FLAG_RXNE);
}

 






关键词: 中断    

院士
2014-11-09 16:39:51     打赏
2楼

楼主 你用得什么中断啊??


话说 这个语句写得好不寻常啊~~

for(i=0x00000080;i!=0x00000000;)//LED  


菜鸟
2014-11-09 18:34:51     打赏
3楼

0x00000080是指led8,从led8开始按位每右移一位就代表一只led

依次按位右移1位循环点亮led8~led1 到led1以后又右移了一位就是0x00000000,这时就不用再右移了。。。

我写了一个无限循环闪烁led8~led0的

void led_on(unsigned int sum)  

{  
    int i;  
    GPIO_SetBits(GPIOC,0x000000ff);
  for(i=0x00000080;;)//LED
  {  
      GPIO_ResetBits(GPIOC,i);            
   delay_ms(50);  
   GPIO_SetBits(GPIOC,i);
   delay_ms(sum); 
   i>>=1; 
   if(i==0x00000000){i=0x00000080;}
  }
}

 


院士
2014-11-09 19:46:53     打赏
4楼
写完之后的效果如何啊?

菜鸟
2014-11-09 19:57:26     打赏
5楼

我贴了视频。

一开始流水灯在循环,从串口发送数据以后就按照数据的内容来闪烁了,

但是中断函数执行完以后,没有继续回主函数循环流水灯,而是停下来等待下一次串口发送数据。

 

话说 怎么知道自己用的是什么中断?除了几个函数, 上面的代码大部分是老师写的,我们自己还不太懂。


高工
2014-11-09 21:00:33     打赏
6楼
还是建议楼主先把代码看明白了再来问呗,再说接收中断中还是先清了标志位在发数据呗

菜鸟
2014-11-09 21:48:04     打赏
7楼
好滴 我再去别人的论坛看看吧

高工
2014-11-09 22:23:18     打赏
8楼
楼主的接受中断函数有问题吧,STM32没有接受缓存,不可以进行深度设置,接受一个字节就进一次接受中断,每次进中断调用一次读语句就可以了,依次接受完所有的数据,你这个貌似是有问题,你可以先把接受的数据赋值给一个局部变量,在进行判断试试,例如:test = USART_ReceiveData(USART1);然后判断test是否为你要的值,在做处理,看其他函数应该没什么问题。

菜鸟
2014-11-09 23:08:16     打赏
9楼

嗯,而且刚才你说到标识位提醒了我。

正在改进中。。


菜鸟
2014-11-09 23:14:37     打赏
10楼
果然之前循环点亮led的程序是有点问题的。。嘿嘿 正在改进

共13条 1/2 1 2 跳转至

回复

匿名不能发帖!请先 [ 登陆 注册 ]