15193|10

113

帖子

0

TA的资源

一粒金砂(高级)

楼主
 

使用STC15遇到外部中断问题 [复制链接]

使用STC15遇到外部中断问题, 我同时使用外部中断1,UART串口1, 硬件SPI。 出现了只有主循环内有UART发送函数时,外部中断才能进入。 如果没有放置UART发送函数。 刚不能进入外部中断1.

---------------------------------------------------------------------------------------------------------

/*---------------------------------------------------------------------*/
/* --- STC MCU Limited ------------------------------------------------*/
/* --- STC15F4K60S4 系列 定时器1用作串口1的波特率发生器举例------------*/
/* --- Mobile: (86)13922805190 ----------------------------------------*/
/* --- Fax: 86-755-82905966 -------------------------------------------*/
/* --- Tel: 86-755-82948412 -------------------------------------------*/
/* --- Web: www.STCMCU.com --------------------------------------------*/
/* 如果要在程序中使用此代码,请在程序中注明使用了宏晶科技的资料及程序   */
/* 如果要在文章中应用此代码,请在文章中注明使用了宏晶科技的资料及程序   */
/*---------------------------------------------------------------------*/

//本示例在Keil开发环境下请选择Intel的8058芯片型号进行编译
//假定测试芯片的工作频率为18.432MHz

//#include "reg52.H"  
#include "STC15F2K60S2.H"
#include "intrins.h"

#include "UART.h"
#include "MyType.h"
#include "config.h"


//sfr AUXR  = 0x8e;               // 辅助寄存器
//sfr P_SW1 = 0xA2;                     // 外设功能切换寄存器1
//sbit P22         = P2^2;

bit busy;


void uartInit(void)
{
        EA = 0;
       
        ACC = P_SW1;
        ACC &= ~(S1_S0 | S1_S1);    //S1_S0=0 S1_S1=0
        P_SW1 = ACC;                //(P3.0/RxD, P3.1/TxD)
   
//  ACC = P_SW1;
//  ACC &= ~(S1_S0 | S1_S1);    //S1_S0=1 S1_S1=0
//  ACC |= S1_S0;               //(P3.6/RxD_2, P3.7/TxD_2)
//  P_SW1 = ACC;  
//  
//  ACC = P_SW1;
//  ACC &= ~(S1_S0 | S1_S1);    //S1_S0=0 S1_S1=1
//  ACC |= S1_S1;               //(P1.6/RxD_3, P1.7/TxD_3)
//  P_SW1 = ACC;  

#if (PARITYBIT == NONE_PARITY)
    SCON = 0x50;                //8位可变波特率
#elif (PARITYBIT == ODD_PARITY) || (PARITYBIT == EVEN_PARITY) || (PARITYBIT == MARK_PARITY)
    SCON = 0xda;                //9位可变波特率,校验位初始为1
#elif (PARITYBIT == SPACE_PARITY)
    SCON = 0xd2;                //9位可变波特率,校验位初始为0
#endif

        //PT1 = 0;                                                                                                                // 定时器0优先级为最低。
        AUXR = 0x40;                                                // 定时器1为1T模式
        TMOD = 0x00;                                                // 定时器1为模式0(16位自动重载)
        TL1 = (65536 - (FOSC/4/BAUD));                   // 设置波特率重装值
        TH1 = (65536 - (FOSC/4/BAUD))>>8;
        TR1 = 1;                                                           // 定时器1开始启动
        ES = 1;                                                     // 使能串口中断
        EA = 1;

        //uartSendString("STC15F2K60S2 \r\n Uart Test !  \r\n");
}

/*----------------------------
UART 中断服务程序
-----------------------------*/
void Uart() interrupt 4 using 2
{
        if (RI)
        {
                RI = 0;                 // 清除RI位
                //P0 = SBUF;              // P0显示串口数据
                //P22 = RB8;              // P2.2显示校验位
        }
        if (TI)
        {
                TI = 0;                 // 清除TI位
                busy = 0;               // 清忙标志
        }
}

/*----------------------------
发送串口数据
----------------------------*/
void uartSendData(BYTE dat)
{
    while (busy);               //等待前面的数据发送完成
    ACC = dat;                  //获取校验位P (PSW.0)
    if (P)                      //根据P来设置校验位
    {
#if (PARITYBIT == ODD_PARITY)
        TB8 = 0;                //设置校验位为0
#elif (PARITYBIT == EVEN_PARITY)
        TB8 = 1;                //设置校验位为1
#endif
    }
    else
    {
#if (PARITYBIT == ODD_PARITY)
        TB8 = 1;                //设置校验位为1
#elif (PARITYBIT == EVEN_PARITY)
        TB8 = 0;                //设置校验位为0
#endif
    }
    busy = 1;
    SBUF = ACC;                 //写数据到UART数据寄存器
}

/*----------------------------
函数名称: uartSendString(char *s)
函数功能: 发送字符串。
发送较多字符时,会出现丢失现像。可能是指针丢失。

----------------------------*/
void uartSendString(char *s)
{       
        while (*s)                  //检测字符串结束标志
        {
                uartSendData(*s++);         //发送当前字符
        }
}
---------------------------------------------------------------------------------------------------



此帖出自单片机论坛

最新回复

楼主 当时具体原因是的啥造成的?我现在也是STC15单片机,遇到了统一的问题,求指导啊  详情 回复 发表于 2016-10-25 08:45
点赞 关注
 

回复
举报

113

帖子

0

TA的资源

一粒金砂(高级)

沙发
 
/*---------------------------------------------------------------------*/
/* --- STC MCU Limited ------------------------------------------------*/
/* --- STC15F4K60S4 系列 SPI的主模式读写外部串行Flash举例(中断方式)----*/
/* --- Mobile: (86)13922805190 ----------------------------------------*/
/* --- Fax: 86-755-82905966 -------------------------------------------*/
/* --- Tel: 86-755-82948412 -------------------------------------------*/
/* --- Web: www.STCMCU.com --------------------------------------------*/
/* 如果要在程序中使用此代码,请在程序中注明使用了宏晶科技的资料及程序   */
/* 如果要在文章中应用此代码,请在文章中注明使用了宏晶科技的资料及程序   */
/*---------------------------------------------------------------------*/

//本示例在Keil开发环境下请选择Intel的8058芯片型号进行编译
//假定测试芯片的工作频率为18.432MHz
//本示例所读写的目标Flash为PM25LV040,本代码已使用U7编程器测试通过

//#include "reg51.h"
#include "SPI.H"

BOOL g_fSpiBusy;                                                                  //SPI的工作状态


/************************************************
SPI中断服务程序
************************************************/
void spi_isr() interrupt 9 using 3
{
    SPSTAT = SPIF | WCOL;                       //清除SPI状态位
    g_fSpiBusy = FALSE;
}


/************************************************
SPI初始化
入口参数: 无
出口参数: 无
说    明:
************************************************/
void InitSpi()
{
        EA = 0;                 // 暂时关闭中断。
       
  ACC = P_SW1;                                                                        // 切换到第一组SPI
  ACC &= ~(SPI_S0 | SPI_S1);                                                          // SPI_S0=0 SPI_S1=0
  P_SW1 = ACC;                                                                        // (P1.2/SS, P1.3/MOSI, P1.4/MISO, P1.5/SCLK)

//    ACC = P_SW1;                                                        // 可用于测试U7,U7使用的是第二组SPI控制Flash
//    ACC &= ~(SPI_S0 | SPI_S1);                                          // SPI_S0=1 SPI_S1=0
//    ACC |= SPI_S0;                                                              // (P2.4/SS_2, P2.3/MOSI_2, P2.2/MISO_2, P2.1/SCLK_2)
//    P_SW1 = ACC;  

//  ACC = P_SW1;                                                                // 切换到第三组SPI
//  ACC &= ~(SPI_S0 | SPI_S1);                                                  // SPI_S0=0 SPI_S1=1
//  ACC |= SPI_S1;                                                              // (P5.4/SS_3, P4.0/MOSI_3, P4.1/MISO_3, P4.3/SCLK_3)
//  P_SW1 = ACC;  


        SPSTAT = SPIF | WCOL;                                                       // 清除SPI状态
        SPI_CS = 1;
        SPCTL = 0x00;                                                                                                                                                                // 清除SPI控掉寄存器.
        // 设置主机, 使能, 主模式 时钟悬空高 后时种沿采样
        // 4分频(SPDHH)  高位先发(DORD)
        SPCTL = SSIG | SPEN | MSTR | CPOL | CPHA  ;  


        //使能SPI传输中断
        IE2 |= ESPI;
        EA = 1;
}

/************************************************
函数名称: 使用SPI方式与Flash进行数据交换
入口参数: dat 准备写入的数据
出口参数: 从Flash中读出的数据
************************************************/
BYTE SpiShift(BYTE dat)
{
    g_fSpiBusy = TRUE;
    SPDAT = dat;                                //触发SPI发送
    while (g_fSpiBusy);                         //等待SPI数据传输完成
   
    return SPDAT;
}


此帖出自单片机论坛
 
 

回复

113

帖子

0

TA的资源

一粒金砂(高级)

板凳
 
本帖最后由 doganup 于 2014-11-12 15:30 编辑

/*---------------------------------------------------------------------*/
/* --- STC MCU Limited ------------------------------------------------*/
/* --- STC15F4K60S4 系列 INT1中断举例----------------------------------*/
/* --- Mobile: (86)13922805190 ----------------------------------------*/
/* --- Fax: 86-755-82905966 -------------------------------------------*/
/* --- Tel: 86-755-82948412 -------------------------------------------*/
/* --- Web: www.STCMCU.com --------------------------------------------*/
/* 如果要在程序中使用此代码,请在程序中注明使用了宏晶科技的资料及程序   */
/* 如果要在文章中应用此代码,请在文章中注明使用了宏晶科技的资料及程序   */
/*---------------------------------------------------------------------*/

//本示例在Keil开发环境下请选择Intel的8058芯片型号进行编译
//假定测试芯片的工作频率为18.432MHz

#include "timer.h"

#define  NoChangedTime 9

#define DEBUG_TIMER

//sbit INT1 = P3^3;

extern unsigned char TIM;
extern unsigned char CAN_Flag;

extern void uartSendString(uint8 * pd);                                        //

/*******************************************************************************
* 函数名  : Exint1_Init
* 描述    : 外部中断1初始化函数
* 输入    : 无
* 输出    : 无
* 返回值  : 无
* 说明    : 无
*******************************************************************************/
void Exint1_Init(void)
{
        EA = 0;                                 // 暂时关闭中断。
        P33 = 1;
  //PX1 = 1;                                // 设置外部中断1的中断优先级为高优先级
  IT1 = 1;                                 // 设置INT1的中断类型 (1:仅下降沿 0:上升沿和下降沿)
  EX1 = 1;                                 // 使能INT1中断
  EA = 1;                                  // 使能总中断        
}

/*******************************************************************************
* 函数名  : Exint1_ISR
* 描述    : 外部中断1中断服务函数
* 输入    : 无
* 输出    : 无
* 返回值  : 无
* 说明    : 用于检测MCP2515中断引脚的中断信号
*******************************************************************************/
void Exint1_ISR(void) interrupt 2 using 1
{
        CAN_Flag = 1;                                                                                                                                //CAN接收到数据标志
/*
        #ifdef DEBUG_TIMER        
                uartSendString("into Interrupt. \r\n");
        #endif
*/
}

此帖出自单片机论坛
 
 
 

回复

113

帖子

0

TA的资源

一粒金砂(高级)

4
 
本帖最后由 doganup 于 2014-11-12 15:40 编辑

void main(void)
{
        uint8 len, i = 1, j = 0;

        // UART初始化。
        uartInit();
                uartSendString(" UART init end。\r\n \r\n");        
        
        // SPI初始化,关闭所有片选。InitSpi()
        InitSpi();
                uartSendString(" SPI init end。\r\n \r\n")

       // 外部中断 1 初始化。
       Exint1_Init();
        while(1)
        {
                        if(CAN_Flag)
                        {
                             uartSendString("into Interrupt. \r\n");        // 2 不然无法进入中断               
                        }
                        else
                        {
                                uartSendString("into Interrupt. \r\n");  //  1 主循环必须有UART发送函数。
                        }
                }
        }
此帖出自单片机论坛
 
 
 

回复

113

帖子

0

TA的资源

一粒金砂(高级)

5
 
我查看过STC15F2K32S 芯片的最下行的最后一个字母是C,应该不是A版的问题。
此帖出自单片机论坛
 
 
 

回复

113

帖子

0

TA的资源

一粒金砂(高级)

6
 
/*---------------------------------------------------------------------*/
/* --- STC MCU Limited ------------------------------------------------*/
/* --- STC15F4K60S4 系列 INT1中断举例----------------------------------*/
/* --- Mobile: (86)13922805190 ----------------------------------------*/
/* --- Fax: 86-755-82905966 -------------------------------------------*/
/* --- Tel: 86-755-82948412 -------------------------------------------*/
/* --- Web: www.STCMCU.com --------------------------------------------*/
/* 如果要在程序中使用此代码,请在程序中注明使用了宏晶科技的资料及程序   */
/* 如果要在文章中应用此代码,请在文章中注明使用了宏晶科技的资料及程序   */
/*---------------------------------------------------------------------*/

//本示例在Keil开发环境下请选择Intel的8058芯片型号进行编译
//假定测试芯片的工作频率为18.432MHz

#include "timer.h"

#define  NoChangedTime 9

#define DEBUG_TIMER

//sbit INT1 = P3^3;

extern unsigned char TIM;
extern unsigned char CAN_Flag;

extern void uartSendString(uint8 * pd);                                        //

/*******************************************************************************
* 函数名  : Exint1_Init
* 描述    : 外部中断1初始化函数
* 输入    : 无
* 输出    : 无
* 返回值  : 无
* 说明    : 无
*******************************************************************************/
void Exint1_Init(void)
{
        EA = 0;                                 // 暂时关闭中断。
        P33 = 1;
  //PX1 = 1;                                // 设置外部中断1的中断优先级为高优先级
  IT1 = 1;                                 // 设置INT1的中断类型 (1:仅下降沿 0:上升沿和下降沿)
  EX1 = 1;                                 // 使能INT1中断
  EA = 1;                                  // 使能总中断      
}

/*******************************************************************************
* 函数名  : Exint1_ISR
* 描述    : 外部中断1中断服务函数
* 输入    : 无
* 输出    : 无
* 返回值  : 无
* 说明    : 用于检测MCP2515中断引脚的中断信号
*******************************************************************************/
void Exint1_ISR(void) interrupt 2 using 1
{
        CAN_Flag = 1;                                       
}
此帖出自单片机论坛
 
 
 

回复

1万

帖子

139

TA的资源

版主

7
 
在程序中检查中断使能设置,只有准许了中断后才会响应中断。
此帖出自单片机论坛

点评

中断EA使能的。中断也好用。我逐步屏蔽代码后,发现中断好用。能进入。通过在中断函数内设置其它IO驱动LED,得到中断成功能反馈显示效果。 因此也发现,中断函数内的变量调用,如CAN_Flag设为1。在主函数内的CAN_Fl  详情 回复 发表于 2014-11-12 18:11
 
个人签名上传了一些书籍资料,也许有你想要的:https://download.eeworld.com.cn/user/chunyang
 
 

回复

113

帖子

0

TA的资源

一粒金砂(高级)

8
 
chunyang 发表于 2014-11-12 17:15
在程序中检查中断使能设置,只有准许了中断后才会响应中断。

中断EA使能的。中断也好用。我逐步屏蔽代码后,发现中断好用。能进入。通过在中断函数内设置其它IO驱动LED,得到中断成功能反馈显示效果。
因此也发现,中断函数内的变量调用,如CAN_Flag设为1。在主函数内的CAN_Flag没有反应。可以描述不准确,就是中断函数内的变量赋值,在main里没有起到作用。

此帖出自单片机论坛
 
 
 

回复

113

帖子

0

TA的资源

一粒金砂(高级)

9
 
本帖最后由 doganup 于 2014-11-12 19:16 编辑

中断能进入, 但是中断函数内的变量赋值不起作用。  如果在主循环内加UART发送函数,就能进入中断。
此帖出自单片机论坛
 
 
 

回复

113

帖子

0

TA的资源

一粒金砂(高级)

10
 
是我代码没弄好,MCP2515  代码部分没清理干净。造的干扰。中断没问题,使用也正常, 谢谢楼上各位的回贴,非常感谢。

最近脑代糊涂
此帖出自单片机论坛
 
 
 

回复

3

帖子

0

TA的资源

一粒金砂(初级)

11
 
doganup 发表于 2014-11-12 20:23
是我代码没弄好,MCP2515  代码部分没清理干净。造的干扰。中断没问题,使用也正常, 谢谢楼上各 ...

楼主 当时具体原因是的啥造成的?我现在也是STC15单片机,遇到了统一的问题,求指导啊
此帖出自单片机论坛
 
 
 

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

随便看看
查找数据手册?

EEWorld Datasheet 技术支持

相关文章 更多>>
关闭
站长推荐上一条 1/9 下一条

 
EEWorld订阅号

 
EEWorld服务号

 
汽车开发圈

About Us 关于我们 客户服务 联系方式 器件索引 网站地图 最新更新 手机版

站点相关: 国产芯 安防电子 汽车电子 手机便携 工业控制 家用电子 医疗电子 测试测量 网络通信 物联网

北京市海淀区中关村大街18号B座15层1530室 电话:(010)82350740 邮编:100190

电子工程世界版权所有 京B2-20211791 京ICP备10001474号-1 电信业务审批[2006]字第258号函 京公网安备 11010802033920号 Copyright © 2005-2025 EEWORLD.com.cn, Inc. All rights reserved
快速回复 返回顶部 返回列表