无法使用SPI运行输入cature模式

时间:2016-07-13 09:45:00

标签: interrupt avr spi atmega atmelstudio

我正在尝试使用ENC28J60模块在AVR ATmega8上运行Web服务器。为此,我得到了示例代码from here。这段代码工作正常。这是我的代码: -

#define F_CPU 8000000UL

#include <avr/io.h>
#include <string.h>
#include "ip_arp_udp_tcp.h"
#include "enc28j60.h"
#include "timeout.h"
#include "avr_compat.h"
#include "net.h"

// please modify the following two lines. mac and ip have to be unique
// in your local area network. You can not have the same numbers in
// two devices:
static uint8_t mymac[6] = {0x54,0x55,0x58,0x10,0x00,0x24};
// how did I get the mac addr? Translate the first 3 numbers into ascii is: TUX
static uint8_t myip[4] = {192,168,24,39};
// listen port for www
#define MYWWWPORT 80
//// listen port for udp
#define MYUDPPORT 1200
//

#define BUFFER_SIZE 450
static uint8_t buf[BUFFER_SIZE+1];

int main(void)
{

    uint16_t plen;
    uint16_t dat_p;
    uint8_t i=0;
    uint8_t payloadlen=0;

    _delay_loop_1(50); 

    /*initialize enc28j60*/
    enc28j60Init(mymac);
    enc28j60clkout(2); // change clkout from 6.25MHz to 12.5MHz
    _delay_loop_1(50); // 12ms
    enc28j60PhyWrite(PHLCON,0x476);
    _delay_loop_1(50); // 12ms

    //init the ethernet/ip layer:
    init_ip_arp_udp_tcp(mymac,myip,MYWWWPORT);

    while(1)
    {
        // get the next new packet:
        plen = enc28j60PacketReceive(BUFFER_SIZE, buf);

        /*plen will ne unequal to zero if there is a valid * packet (without crc error) */
        if(plen==0)
        {
            continue;
        }
        // arp is broadcast if unknown but a host may also
        // verify the mac address by sending it to 
        // a unicast address.
        if(eth_type_is_arp_and_my_ip(buf,plen))
        {
            make_arp_answer_from_request(buf);
            continue;
        }
        // check if ip packets (icmp or udp) are for us:
        if(eth_type_is_ip_and_my_ip(buf,plen)==0)
        {
        continue;
        }


        if(buf[IP_PROTO_P]==IP_PROTO_ICMP_V && buf[ICMP_TYPE_P]==ICMP_TYPE_ECHOREQUEST_V)
        {
            // a ping packet, let's send pong
            make_echo_reply_from_request(buf,plen);
            continue;
        }
        // tcp port www start, compare only the lower byte
        if (buf[IP_PROTO_P]==IP_PROTO_TCP_V&&buf[TCP_DST_PORT_H_P]==0&&buf[TCP_DST_PORT_L_P]==MYWWWPORT)
        {
            if (buf[TCP_FLAGS_P] & TCP_FLAGS_SYN_V)
            {
                make_tcp_synack_from_syn(buf);
                // make_tcp_synack_from_syn does already send the syn,ack
                continue;
            }
            if (buf[TCP_FLAGS_P] & TCP_FLAGS_ACK_V)
            {
                init_len_info(buf); // init some data structures
                // we can possibly have no data, just ack:
                dat_p=get_tcp_data_pointer();
                if (dat_p==0)
                {
                    if (buf[TCP_FLAGS_P] & TCP_FLAGS_FIN_V)
                    {
                        // finack, answer with ack
                        make_tcp_ack_from_any(buf);
                    }

                    // just an ack with no data, wait for next packet
                    continue;
                }
                if (strncmp("GET ",(char *)&(buf[dat_p]),4)!=0)
                {
                    plen=fill_tcp_data_p(buf,0,PSTR("HTTP/1.0 200 OK\r\nContent-Type: text/html\r\n\r\n<h1>200 OK</h1>"));
                }
                else
                {
                    // Web Code
                    plen=fill_tcp_data_p(buf,0,PSTR("HTTP/1.0 200 OK\r\nContent-Type: text/html\r\n\r\n<p>PLANETCAST MEDIA SERVICES LTD</p>"));

                    plen=fill_tcp_data_p(buf,plen,PSTR("<body>"));
                    plen=fill_tcp_data_p(buf,plen,PSTR("<input type=\"text\" id=\"myurl\" name=\"url\" placeholder=\"Enter Url\"/><br>"));
                    plen=fill_tcp_data_p(buf,plen,PSTR("<input type=\"submit\" id=\"clickbutton\" name=\"Click Here\" />"));
                    plen=fill_tcp_data_p(buf,plen,PSTR("<script type=\"text/javascript\">"));
                    plen=fill_tcp_data_p(buf,plen,PSTR("document.getElementById(\"clickbutton\").onclick = function(){"));                          
                    plen=fill_tcp_data_p(buf,plen,PSTR("var url = document.getElementById(\"myurl\").value;"));
                    plen=fill_tcp_data_p(buf,plen,PSTR("location.href=url;"));
                    plen=fill_tcp_data_p(buf,plen,PSTR("};"));
                    plen=fill_tcp_data_p(buf,plen,PSTR("</script>"));   
                    plen=fill_tcp_data_p(buf,plen,PSTR("</body"));
                }


                make_tcp_ack_from_any(buf); // send ack for http get
                make_tcp_ack_with_data(buf,plen); // send data
                continue;
           }

      }
      // udp interface:
      if (buf[IP_PROTO_P]==IP_PROTO_UDP_V)
      {
        payloadlen=buf[UDP_LEN_L_P]-UDP_HEADER_LEN;
        // the received command has to start with t and be 4 char long
        // e.g "test\0"
        if (buf[UDP_DATA_P]=='t' && payloadlen==5)
        {
            make_udp_reply_from_request(buf,"hello",6,MYUDPPORT);
        }
      }
   }
   return (0);
}

现在我想添加输入捕获模式,所以我添加interrupt header file然后在main()中启动输入捕获模式,然后引入sei()函数。现在我的代码看起来像这样: -

#define F_CPU 8000000UL

#include <avr/io.h>
#include <string.h>
#include "ip_arp_udp_tcp.h"
#include "enc28j60.h"
#include "timeout.h"
#include "avr_compat.h"
#include "net.h"
#include <avr/interrupt.h>
// please modify the following two lines. mac and ip have to be unique
// in your local area network. You can not have the same numbers in
// two devices:
static uint8_t mymac[6] = {0x54,0x55,0x58,0x10,0x00,0x24};
// how did I get the mac addr? Translate the first 3 numbers into ascii is: TUX
static uint8_t myip[4] = {192,168,24,39};
// listen port for www
#define MYWWWPORT 80
//// listen port for udp
#define MYUDPPORT 1200
//

#define BUFFER_SIZE 450
static uint8_t buf[BUFFER_SIZE+1];

int main(void)
{


    TCCR1A = 0;
    TCCR1B = (1<<ICNC1)|(1<<ICES1)|(1<<CS11);
    TIMSK = (1<<TICIE1);
    TCNT1 = 0;
    sei();
    uint16_t plen;
    uint16_t dat_p;
    uint8_t i=0;
    uint8_t payloadlen=0;

    _delay_loop_1(50); 

    /*initialize enc28j60*/
    enc28j60Init(mymac);
    enc28j60clkout(2); // change clkout from 6.25MHz to 12.5MHz
    _delay_loop_1(50); // 12ms
    enc28j60PhyWrite(PHLCON,0x476);
    _delay_loop_1(50); // 12ms

    //init the ethernet/ip layer:
    init_ip_arp_udp_tcp(mymac,myip,MYWWWPORT);

    while(1)
    {
        // get the next new packet:
        plen = enc28j60PacketReceive(BUFFER_SIZE, buf);

        /*plen will ne unequal to zero if there is a valid * packet (without crc error) */
        if(plen==0)
        {
            continue;
        }
        // arp is broadcast if unknown but a host may also
        // verify the mac address by sending it to 
        // a unicast address.
        if(eth_type_is_arp_and_my_ip(buf,plen))
        {
            make_arp_answer_from_request(buf);
            continue;
        }
        // check if ip packets (icmp or udp) are for us:
        if(eth_type_is_ip_and_my_ip(buf,plen)==0)
        {
        continue;
        }


        if(buf[IP_PROTO_P]==IP_PROTO_ICMP_V && buf[ICMP_TYPE_P]==ICMP_TYPE_ECHOREQUEST_V)
        {
            // a ping packet, let's send pong
            make_echo_reply_from_request(buf,plen);
            continue;
        }
        // tcp port www start, compare only the lower byte
        if (buf[IP_PROTO_P]==IP_PROTO_TCP_V&&buf[TCP_DST_PORT_H_P]==0&&buf[TCP_DST_PORT_L_P]==MYWWWPORT)
        {
            if (buf[TCP_FLAGS_P] & TCP_FLAGS_SYN_V)
            {
                make_tcp_synack_from_syn(buf);
                // make_tcp_synack_from_syn does already send the syn,ack
                continue;
            }
            if (buf[TCP_FLAGS_P] & TCP_FLAGS_ACK_V)
            {
                init_len_info(buf); // init some data structures
                // we can possibly have no data, just ack:
                dat_p=get_tcp_data_pointer();
                if (dat_p==0)
                {
                    if (buf[TCP_FLAGS_P] & TCP_FLAGS_FIN_V)
                    {
                        // finack, answer with ack
                        make_tcp_ack_from_any(buf);
                    }

                    // just an ack with no data, wait for next packet
                    continue;
                }
                if (strncmp("GET ",(char *)&(buf[dat_p]),4)!=0)
                {
                    plen=fill_tcp_data_p(buf,0,PSTR("HTTP/1.0 200 OK\r\nContent-Type: text/html\r\n\r\n<h1>200 OK</h1>"));
                }
                else
                {
                    // Web Code
                    plen=fill_tcp_data_p(buf,0,PSTR("HTTP/1.0 200 OK\r\nContent-Type: text/html\r\n\r\n<p>PLANETCAST MEDIA SERVICES LTD</p>"));

                    plen=fill_tcp_data_p(buf,plen,PSTR("<body>"));
                    plen=fill_tcp_data_p(buf,plen,PSTR("<input type=\"text\" id=\"myurl\" name=\"url\" placeholder=\"Enter Url\"/><br>"));
                    plen=fill_tcp_data_p(buf,plen,PSTR("<input type=\"submit\" id=\"clickbutton\" name=\"Click Here\" />"));
                    plen=fill_tcp_data_p(buf,plen,PSTR("<script type=\"text/javascript\">"));
                    plen=fill_tcp_data_p(buf,plen,PSTR("document.getElementById(\"clickbutton\").onclick = function(){"));                          
                    plen=fill_tcp_data_p(buf,plen,PSTR("var url = document.getElementById(\"myurl\").value;"));
                    plen=fill_tcp_data_p(buf,plen,PSTR("location.href=url;"));
                    plen=fill_tcp_data_p(buf,plen,PSTR("};"));
                    plen=fill_tcp_data_p(buf,plen,PSTR("</script>"));   
                    plen=fill_tcp_data_p(buf,plen,PSTR("</body"));
                }


                make_tcp_ack_from_any(buf); // send ack for http get
                make_tcp_ack_with_data(buf,plen); // send data
                continue;
           }

      }
      // udp interface:
      if (buf[IP_PROTO_P]==IP_PROTO_UDP_V)
      {
        payloadlen=buf[UDP_LEN_L_P]-UDP_HEADER_LEN;
        // the received command has to start with t and be 4 char long
        // e.g "test\0"
        if (buf[UDP_DATA_P]=='t' && payloadlen==5)
        {
            make_udp_reply_from_request(buf,"hello",6,MYUDPPORT);
        }
      }
   }
   return (0);
}


ISR(TIMER1_CAPT_vect)
{
    //do something
}

现在,当我运行我的代码时,我的浏览器上没有网页。所以,我评论sei()函数。在此之后我的代码工作正常。所以,我检查enc28j60.c中的SPI设置。据我所知,SPI不是在中断运行,所以它不应受sei()的影响。以下是enc28j60.c中的SPi设置: -

#define ENC28J60_CONTROL_PORT   PORTB
#define ENC28J60_CONTROL_DDR    DDRB
#define ENC28J60_CONTROL_CS     2
#define ENC28J60_CONTROL_SO 4
#define ENC28J60_CONTROL_SI 3
#define ENC28J60_CONTROL_SCK 5

void enc28j60Init(uint8_t* macaddr)
{
    // initialize I/O
        // ss as output:
    ENC28J60_CONTROL_DDR |= 1<<ENC28J60_CONTROL_CS;
    CSPASSIVE; // ss=0
        //  
    ENC28J60_CONTROL_DDR  |= 1<<ENC28J60_CONTROL_SI | 1<<ENC28J60_CONTROL_SCK; // mosi, sck output
    cbi(ENC28J60_CONTROL_DDR,ENC28J60_CONTROL_SO); // MISO is input
        //
        cbi(ENC28J60_CONTROL_PORT,ENC28J60_CONTROL_SI); // MOSI low
        cbi(ENC28J60_CONTROL_PORT,ENC28J60_CONTROL_SCK); // SCK low

那么,任何人都可以告诉我为什么我的SPI模式受到sei()函数的影响以及如何摆脱它。

1 个答案:

答案 0 :(得分:0)

我还没有阅读你的所有代码,但我认为你们都是在打断你们。在正常模式下,定时器到达顶部时不会复位。尝试使用ISR中的TCNT1 = 0;