搜索
bottom↓
回复: 3

请问马老师,AVR的TWI做主机是不是不能使用中断方式阿?

[复制链接]

出0入0汤圆

发表于 2005-5-22 12:10:43 | 显示全部楼层 |阅读模式
我用M16做主机,M8做从机(M8中断方式正常),当M16不使用中断方式正常。使用中断方式出现怪异的结果



以下是我的测试程序(节选)

int main(void)

{

        // 设波特率为9600

        Init_UART(51);

        // 设置看门狗

        wdt_enable(WDTO_60MS);

        // 允许睡眠模式

        set_sleep_mode(0);

        // TCCR0分频64

        TCCR0 = 0x03;

        // 开定时器0中断

        //sbi(TIMSK,TOIE0);

        // 设置TWI

        TWBR = (CPU_CLOCK/SCL_CLK-16)/2;

        PORTC |= 0x03;

        // 允许全局中断

        sei();

        print("Start
");

        gcSignal = 0;

        TWI_TxHead = 0;TWI_RxHead = 0;TWI_TxTail = 0;TWI_RxTail = 0;

        unsigned char ascii[3] = {0,0,0};

       

        while(1)

        {

                wdt_reset();

                if(bit_is_set(gcSignal, UART_RECEIVED))

                {

                        cbi(gcSignal, UART_RECEIVED);

                        TransmitByte(UART_RxBuf[UART_RxHead]);print("
");        //回显

                        TWI_Send_Byte(UART_RxBuf[UART_RxHead]);

                        UART_RxHead = (UART_RxHead + 1) & UART_RX_BUFFER_MASK;

                }

                if(bit_is_set(gcSignal, TWI_RECEIVED))

                {

                        cbi(gcSignal, TWI_RECEIVED);

                        print("TWSR = ");char_to_ascii(gcTWSR, ascii);print(ascii);print("
");

                        switch(gcTWSR)

                        {

                        case TW_START:                        //0x08

                                if(gcTWI_State == TWI_START)

                                {

                                        gcTWI_State = TWI_SLA_W;

                                        TWDR = 0x02 | TW_WRITE;

                                        TWCR = (1<<TWINT) | (1<<TWEN) | (1<<TWIE);

                                }

                                break;

                        case TW_REP_START:                //0x10

                                if(gcTWI_State == TWI_START)

                                {

                                        gcTWI_State = TWI_SLA_W;

                                        TWDR = 0x02 | TW_WRITE;

                                        TWCR = (1<<TWINT) | (1<<TWEN) | (1<<TWIE);

                                }

                                break;

                        case TW_MT_SLA_ACK:                //0x18

                                if(gcTWI_State == TWI_SLA_W)

                                {

                                        gcTWI_State = TWI_DATA_W;

                                        TWI_TxTail = (TWI_TxTail + 1) & TWI_TX_BUFFER_MASK;

                                        TWDR = TWI_TxBuf[TWI_TxTail];

                                        TWCR = (1<<TWINT) | (1<<TWEN) | (1<<TWIE);

                                }

                                break;

                        case TW_MT_SLA_NACK:        //0x20

                                if(gcTWI_State == TWI_SLA_W)

                                {

                                        gcTWI_State = TWI_DATA_W;

                                        TWI_TxTail = (TWI_TxTail + 1) & TWI_TX_BUFFER_MASK;

                                        TWDR = TWI_TxBuf[TWI_TxTail];

                                        TWCR = (1<<TWINT) | (1<<TWEN) | (1<<TWIE);

                                }

                                break;

                        case TW_MT_DATA_ACK:        //0x28

                                if(gcTWI_State == TWI_DATA_W)

                                {

                                        gcTWI_State = TWI_STOP;

                                        TWCR = (1<<TWINT) | (1<<TWEN) | (1<<TWIE) | (1<<TWSTO);

                                }

                                break;

                        case TW_MT_DATA_NACK:        //0x30

                                if(gcTWI_State == TWI_DATA_W)

                                {

                                        gcTWI_State = TWI_STOP;

                                        TWCR = (1<<TWINT) | (1<<TWEN) | (1<<TWIE) | (1<<TWSTO);

                                }

                                break;

                        case TW_MR_SLA_ACK:                //0x40

                                break;

                        case TW_MR_SLA_NACK:        //0x48

                                break;

                        case TW_MR_DATA_ACK:        //0x50

                                break;

                        case TW_MR_DATA_NACK:        //0x58

                                break;

                        case TW_NO_INFO:                //0xF8

                                break;

                        default:

                                TWCR = (1<<TWINT) | (1<<TWEN) | (1<<TWIE) | (1<<TWSTO);

                        }

                }

        }

}





SIGNAL(SIG_UART_DATA)

{

        /* check if all data is transmitted */

        if(UART_TxHead != UART_TxTail )

        {

                /* calculate buffer index */

                UART_TxTail = (UART_TxTail + 1) & UART_TX_BUFFER_MASK;

                UDR = UART_TxBuf[UART_TxTail]; /* start transmition        */

        }

        else cbi(UCSRB,UDRIE);        // disable UDR interrupt

}



SIGNAL(SIG_UART_RECV)

{

        unsigned char cReceivedByte;

        cReceivedByte = UDR;

        UART_RxBuf[UART_RxTail] = cReceivedByte;

        UART_RxTail = (UART_RxTail + 1) & UART_RX_BUFFER_MASK;

        sbi(gcSignal, UART_RECEIVED);

}



SIGNAL(SIG_2WIRE_SERIAL)

{

        gcTWSR = TWSR;

        sbi(gcSignal, TWI_RECEIVED);

}



-----此内容被Tomcat于2005-05-22,12:11:12编辑过


-----此内容被Tomcat于2005-05-22,12:40:36编辑过

阿莫论坛20周年了!感谢大家的支持与爱护!!

一只鸟敢站在脆弱的枝条上歇脚,它依仗的不是枝条不会断,而是自己有翅膀,会飞。

出0入0汤圆

 楼主| 发表于 2005-5-22 12:37:18 | 显示全部楼层
测试程序的流程是当从串口接受到一个字符时,回显字符并传输该字符到TWI口,TWI中断后打印TWSR的值再判断作什么处理



当收到一个字符并发送到TWI理想的结果应该是回显(假设输入的字符是'g')

Start

g

TWSR = 08

TWSR = 18

TWSR = 28



但是当中断服务程序为这样时

SIGNAL(SIG_2WIRE_SERIAL)

{

        gcTWSR = TWSR;

        sbi(gcSignal, TWI_RECEIVED);

        TWCR = 1<<TWINT; // 清TWINT

}

回显

Start

g

TWSR = 08 //没动静了,再敲键盘也是同样的结果



当中断服务程序这样时

SIGNAL(SIG_2WIRE_SERIAL)

{

        gcTWSR = TWSR;

        sbi(gcSignal, TWI_RECEIVED);

        cbi(TWCR, TWIE);  // 禁止TWI中断

}



Start

d          //我敲的字符

TWSR = 08

TWSR = 48  //TWSR的值居然是0x48,搞不懂

d

TWSR = 10

TWSR = 48

d

TWSR = 10

TWSR = 48



写成这样,中断程序对TWI不作任何处理

SIGNAL(SIG_2WIRE_SERIAL)

{

        gcTWSR = TWSR;

        sbi(gcSignal, TWI_RECEIVED);

}

串口回送

Start

d

TWSR = 08

TWSR = F8

TWSR = 18

TWSR = F8

TWSR = 28

TWSR = F8

d

TWSR = 08

TWSR = F8

TWSR = 18

TWSR = F8

TWSR = 28

TWSR = F8

还算正常,可以用,但是由于TWINT还是1,TWI中断也没有屏蔽,TWI一直在不停的中断,程序效率很低



我不知道哪里错了,搞了3天,快崩溃了。怀疑是不是AVR TWI有Bug,不过这种事一般都是我出错。我在网上查了半天,好像没人用TWI的主机中断方式,都是等待。



马老师如果有空的时候帮看看吧,要是忙就直接删了,不想太麻烦你



谢谢!

出0入4汤圆

发表于 2005-6-17 15:52:27 | 显示全部楼层
我也想问这个问题:AVR的TWI做主机是不是不能使用中断方式阿

出0入0汤圆

发表于 2005-6-18 18:53:32 | 显示全部楼层
请参考《M128》书中第五章的例子,里面有关于TWI主机的参考,使用中断+状态机+数据缓冲器。
回帖提示: 反政府言论将被立即封锁ID 在按“提交”前,请自问一下:我这样表达会给举报吗,会给自己惹麻烦吗? 另外:尽量不要使用Mark、顶等没有意义的回复。不得大量使用大字体和彩色字。【本论坛不允许直接上传手机拍摄图片,浪费大家下载带宽和论坛服务器空间,请压缩后(图片小于1兆)才上传。压缩方法可以在微信里面发给自己(不要勾选“原图),然后下载,就能得到压缩后的图片】。另外,手机版只能上传图片,要上传附件需要切换到电脑版(不需要使用电脑,手机上切换到电脑版就行,页面底部)。
您需要登录后才可以回帖 登录 | 注册

本版积分规则

手机版|Archiver|amobbs.com 阿莫电子技术论坛 ( 粤ICP备2022115958号, 版权所有:东莞阿莫电子贸易商行 创办于2004年 (公安交互式论坛备案:44190002001997 ) )

GMT+8, 2024-5-23 17:07

© Since 2004 www.amobbs.com, 原www.ourdev.cn, 原www.ouravr.com

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