我在单片机的串口发送的中断程序中设置了一个计数器,使其能发送同样的数据n次后发送下一个数据n次,但是运行后发现串口每个数据只发送了3、4次就换下一个数据了,我猜想是因为变量n的初始值在进入中断的时候被压入堆栈,所以每次退出是都又把原始值又弹回去了,所以每次都只在初始值附近徘徊,这是我的猜想,不知道对不对,盼望各位给我解答一下,最好能说一下怎么修改,谢谢了。
把你的程序发上来看下,这么说没有办法的。有可能是在中断外,修改了数据
哦,我想错了,看来不是那个问题,把代码发出来,这段程序是个测试程序,主要功能是把UART_Buffer中的11个数依次发送出来,每个数发送很多遍,每两个不同的数用很多个“11”隔开(这是我自定义的空闲字符),读过程序大家可以看出,我用一个int count和一个 unsigned char count1来延时,而且每个字符我发送的时间等于64000*8次count++的时间,关键是我把count++写在了中断程序中,那么应该是每个字符的发送时间等于64000*8次中断的时间,也就是每个字符我发送了64000*8次,但实际上在相同的时间里,相同的波特率下,在接收端只接收了大约600个字符,请问这是怎么回事,难道要中断很多次才能把一个数据发送出去?
- #include // SFR declarations
- #include
- //-----------------------------------------------------------------------------
- // Global CONSTANTS
- //-----------------------------------------------------------------------------
- #define SYSTEMCLOCK 24500000 // SYSCLK frequency in Hz
- #define BAUDRATE 2400 // Baud rate of UART in bps
- //-----------------------------------------------------------------------------
- // Function PROTOTYPES
- //-----------------------------------------------------------------------------
- void SYSCLK_Init (void);
- void UART0_Init (void);
- void PORT_Init (void);
- void Timer2_Init (int);
- //-----------------------------------------------------------------------------
- // Global Variables
- //-----------------------------------------------------------------------------
- #define UART_BUFFERSIZE 11
- unsigned char UART_Buffer[UART_BUFFERSIZE]=
- {0,1,2,3,4,5,6,7,9,10,12};
- //unsigned char UART_Buffer_Size = 0;
- //unsigned char UART_Input_First = 0;
- //unsigned char UART_Output_First = 0;
- unsigned char TX_Ready =1;//发送准备好
- static char Byte;
- unsigned char index=0,count1=0;
- unsigned int count=0;
- //-----------------------------------------------------------------------------
- // MAIN Routine
- //-----------------------------------------------------------------------------
- void main (void)
- {
- PCA0MD &= ~0x40; // WDTE = 0 (clear watchdog timer
- // enable)
- Byte=UART_Buffer[0];
- PORT_Init(); // Initialize Port I/O
- SYSCLK_Init (); // Initialize Oscillator
- UART0_Init(); //初始化UART0串口
- // RI0 = 0;//禁止接收数据,只发送
- EA = 1;//开启中断 EA:IE.7 open all interrupts,descide by their marks
-
- while(1)
- {
- if(TX_Ready==1)
- {
- TX_Ready=0;
- if(count==64000)
- {
- count1++;
- if(count1==8)
- {
- Byte = 11;//发送空闲字符
- }
- if(count1==16)
- {
- index++;
- index%=11;
- Byte = UART_Buffer[index];
- count1=0;
- }
- count=0;
- }
- TI0 = 1;
- }
- }
- }
- //-----------------------------------------------------------------------------
- // Initialization Subroutines
- //-----------------------------------------------------------------------------
- //-----------------------------------------------------------------------------
- // PORT_Init
- //-----------------------------------------------------------------------------
- //
- // Return Value : None
- // Parameters : None
- //
- // Configure the Crossbar and GPIO ports.
- //
- // P0.4 digital push-pull UART TX
- // P0.5 digital open-drain UART RX
- //
- //-----------------------------------------------------------------------------
- void PORT_Init (void)
- {//P0MDOUT:P0口输出方式寄存器
- P0MDOUT |= 0x10; // Enable UTX as push-pull outputP0.4为推挽式
- XBR0 = 0x01; //Enable UART on P0.4(TX) and P0.5(RX)TX,RX连到P0.4,P0.5
- XBR1 = 0x40; // Enable crossbar and weak pull-ups交叉开关使能
- }
- //-----------------------------------------------------------------------------
- // SYSCLK_Init
- //-----------------------------------------------------------------------------
- //
- // Return Value : None
- // Parameters : None
- //
- // This routine initializes the system clock to use the internal oscillator
- // at its maximum frequency.
- // Also enables the Missing Clock Detector.
- //-----------------------------------------------------------------------------
- void SYSCLK_Init (void)
- {
- OSCICN |= 0x03; // Configure internal oscillator for
- // its maximum frequency
- RSTSRC = 0x04; // Enable missing clock detector
- }
- //-----------------------------------------------------------------------------
- // UART0_Init
- //-----------------------------------------------------------------------------
- //
- // Return Value : None
- // Parameters : None
- //
- // Configure the UART0 using Timer1, for and 8-N-1.
- // UART0的波特率由定时器1工作在8位自动重装方式产生,溢出信号经过2分频后产生波特
- // 率。UART的波特率=[定时器1的时钟频率/(256-T1H)]/2,
- //-----------------------------------------------------------------------------
- void UART0_Init (void)
- {
- SCON0 = 0x00; // SCON0: 8-bit variable bit rate
- // level of STOP bit is ignored
- // RX enabled
- // ninth bits are zeros
- // clear RI0 and TI0 bits
- //receive is forbidden.
- if (SYSTEMCLOCK/BAUDRATE/2/256 < 1) {
- TH1 = -(SYSTEMCLOCK/BAUDRATE/2);
- CKCON &= ~0x0B;// 定时器0使用系统时钟
- CKCON |= 0x08;// 定时器1使用系统时钟
- } else if (SYSTEMCLOCK/BAUDRATE/2/256 < 4) {
- TH1 = -(SYSTEMCLOCK/BAUDRATE/2/4);
- CKCON &= ~0x0B; // 定时器0使用系统时钟
- CKCON |= 0x01; //系统时钟4分频 因为此时位3为0,所以定时器1使用4分频
- } else if (SYSTEMCLOCK/BAUDRATE/2/256 < 12) {
- TH1 = -(SYSTEMCLOCK/BAUDRATE/2/12);
- CKCON &= ~0x0B; // 定时器1使用系统时钟12分频
- } else {
- TH1 = -(SYSTEMCLOCK/BAUDRATE/2/48);
- CKCON &= ~0x0B; // 定时器1使用系统时钟48分频
- CKCON |= 0x02;
- }
- TL1 = TH1; // init Timer1
- TMOD &= ~0xf0; // 定时器1在TR1=1时工作,使用T1M定义的时钟,即上面的结果
- TMOD |= 0x20; //工作在方式2,自动重装
- TR1 = 1; // START Timer1
- TX_Ready = 1; // Flag showing that UART can transmit
- IP |= 0x10; // Make UART high priority
- ES0 = 1; // Enable UART0 interrupts
- }
- //-----------------------------------------------------------------------------
- // Interrupt Service Routines
- //-----------------------------------------------------------------------------
- //-----------------------------------------------------------------------------
- // UART0_Interrupt
- //-----------------------------------------------------------------------------
- //
- // This routine is invoked whenever a character is entered or displayed on the
- // Hyperterminal.
- //
- //-----------------------------------------------------------------------------
- void UART0_Interrupt (void) interrupt 4
- {
-
- if (TI0 == 1&&TX_Ready==0) // Check if transmit flag is set
- {
- count++;
- SBUF0 = Byte;
- TI0 = 0; // Clear interrupt flag
- TX_Ready=1;
- }
- }
- //-----------------------------------------------------------------------------
- // End Of File
- //---------------------------------------------------------------
这样用的变量
用volatile声明一下
另让系统优化了,不然怎么死都不知道
还有就是,在读写的时候,要注意控制访问
不然,如果不知道谁动了这个变量的话,那也会死得很惨
呵呵
LZ可以找相关的内容:临界变量