Robofun 機器人論壇

 找回密碼
 申請會員
搜索
熱搜: 活動 交友 discuz
查看: 4753|回復: 8
打印 上一主題 下一主題

ATmega16 機器人控制器 公開程式分享

[複製鏈接]
xu3u4rmp4 該用戶已被刪除
跳轉到指定樓層
1#
發表於 2011-8-19 20:09:49 | 只看該作者 |只看大圖 回帖獎勵 |倒序瀏覽 |閱讀模式
本帖最後由 xu3u4rmp4 於 2011-8-27 01:00 編輯

好像大家興趣缺缺.那就先改成8軸.有需要再向我索取完整32軸資料
完整電路圖晚點會補上
PORTA.0接74595串行數據輸入   DS
PORTA.1接74595移位時鐘脈衝   SH_CP
PORTA.2接74595輸出鎖存器控制脈衝   ST_CP






















AVR部分

//ICC-AVR application builder : 2011/8/19 下午 10:25:37
// Target : M16
// Crystal: 14.7456Mhz
#include <iom16v.h>
#include <macros.h>
unsigned char a=0,temp=0xff;
unsigned int i=0,model=1,c,R=0;
unsigned char unb,u1,u2;

unsigned char Out_pin[8]={0xfe,0xfd,0xfb,0xf7,0xef,0xdf,0xbf,0x7f};   

unsigned char PWM_in[32]={0x50,200,80,220,150,150,150,150,
                         150,150,150,150,150,150,150,150,
                         150,150,150,150,150,150,150,150,
                         150,150,150,150,150,150,150,150};
unsigned char PWM_out[32]={100,200,80,220,150,150,150,150,
                         150,150,150,150,150,150,150,150,
                         150,150,150,150,150,150,150,150,
                         150,150,150,150,150,150,150,150};
                  
#define  SDATA_595_1_1 PORTA|=BIT(PA0);  //串行數據輸入   DS
#define  SDATA_595_1_0 PORTA&=~BIT(PA0);   
#define  SCLK_595_1_1 PORTA|=BIT(PA1);    //移位時鐘脈衝   SH_CP
#define  SCLK_595_1_0 PORTA&=~BIT(PA1);   
#define  RCK_595_1_1 PORTA|=BIT(PA2);    //輸出鎖存器控制脈衝   ST_CP
#define  RCK_595_1_0 PORTA&=~BIT(PA2);   

void WR_OUT_595_1(unsigned char DATA);

void PortA_model(void);

void Delay(void)
{
unsigned char i;
for(i=2;i>0;i--);
}
unsigned char Uart_Receive(void)
{
while (!(UCSRA & (1<<RXC)));
return UDR;   
}

{

MCUCSR|=(1<<7);
MCUCSR|=(1<<7);
PORTA = 0xFF;
DDRA  = 0xFF;
PORTB = 0xFF;
DDRB  = 0xFF;
PORTC = 0xFF; //m103 output only
DDRC  = 0xFF;
PORTD = 0x02;
DDRD  = 0x02;
}
//UART0 initialize
// desired baud rate: 9600
// actual: baud rate:9600 (0.0%)
// char size: 8 bit
// parity: Disabled
void uart0_init(void)
{
UCSRB = 0x00; //disable while setting baud rate
UCSRA = 0x00;
UCSRC = BIT(URSEL) | 0x06;
UBRRL = 0x5F; //set baud rate lo
UBRRH = 0x00; //set baud rate hi
UCSRB = 0x18;
}


//TIMER0 initialize - prescale:1024
// WGM: Normal
// desired value: 5mSec請自行把計時器改成20mS
// actual value:  4.931mSec (1.4%)
void timer0_init(void)
{
TCCR0 = 0x00; //stop
TCNT0 = 0xB9; //set count
OCR0  = 0x47;  //set compare
TCCR0 = 0x05; //start timer
}
void init_devices(void)
{
//stop errant interrupts until set up
CLI(); //disable all interrupts
port_init();
timer0_init();
uart0_init();

MCUCR = 0x00;
GICR  = 0x00;
TIMSK = 0x01; //timer interrupt sources
SEI(); //re-enable interrupts
//all peripherals are now initialized
}
#pragma interrupt_handler timer0_ovf_isr:10
void timer0_ovf_isr(void)
{
TCNT0 = 0xB9; //reload counter value
     temp=0xff;   
     WR_OUT_595_1(temp);   
     for(R=0;R<8;R++)
     {                                                                     
      PWM_out[R]=PWM_in[R];
     }
   for(R=0;R<300;R++)
   {
        Delay();
      if(R==PWM_out[0]){temp=temp&Out_pin[0];WR_OUT_595_1(temp);}   
       if(R==PWM_out[1]){temp=temp&Out_pin[1];WR_OUT_595_1(temp);}
      if(R==PWM_out[2]){temp=temp&Out_pin[2];WR_OUT_595_1(temp);}   
       if(R==PWM_out[3]){temp=temp&Out_pin[3];WR_OUT_595_1(temp);}
      if(R==PWM_out[4]){temp=temp&Out_pin[4];WR_OUT_595_1(temp);}   
       if(R==PWM_out[5]){temp=temp&Out_pin[5];WR_OUT_595_1(temp);}
      if(R==PWM_out[6]){temp=temp&Out_pin[6];WR_OUT_595_1(temp);}   
       if(R==PWM_out[7]){temp=temp&Out_pin[7];WR_OUT_595_1(temp);}   
   }     
}






void main(void)
{
init_devices();        
       while(1)
        {
unb=Uart_Receive();
u1=Uart_Receive();
u2=Uart_Receive();
PWM_in[unb]=u1+u2;

        }

}




void WR_OUT_595_1(unsigned char DATA)
{
   {
        unsigned char j,x;
         for (j=0;j<8;j++)
        {
          x=DATA&0x80;
           if(x==0)  
              {
             SDATA_595_1_0;
            }
            else  
            {
             SDATA_595_1_1;
            }     
          SCLK_595_1_1;    //上升沿發生移位
          SCLK_595_1_0;
        DATA=DATA<<1;
       }
      RCK_595_1_0;
      RCK_595_1_1;  //上升沿將數據送到輸出鎖存器
      RCK_595_1_0;
   }      
}

VB部分
簡單左中右例子
傳輸80-220即是對應的0.8mS~2.2mS PWM寬
由於傳輸超過128會不正常(因為是ASC碼的關係)
所以以簡單的方式解決.就是分2次傳

Private Sub Form_Load()

    MSComm1.CommPort = 3
    MSComm1.Settings = "9600,N,8,1"
    MSComm1.InputMode = 1
    MSComm1.InputLen = 256
    MSComm1.RThreshold = 1
  MSComm1.PortOpen = True
    Label1.Caption = HScroll1.Value
   
End Sub
Private Sub Command1_Click()
Cmd_array = &H0
MSComm1.Output = Chr(Cmd_array)
a = 120
b = 100
MSComm1.Output = Chr(a)
MSComm1.Output = Chr(b)
Label1.Caption = 220
HScroll1.Value = 220
End Sub

Private Sub Command2_Click()
Cmd_array = &H0
MSComm1.Output = Chr(Cmd_array)
a = 100
b = 50
MSComm1.Output = Chr(a)
MSComm1.Output = Chr(b)
Label1.Caption = 150
HScroll1.Value = 150
End Sub

Private Sub Command3_Click()
Cmd_array = &H0
MSComm1.Output = Chr(Cmd_array)
a = 40
b = 40
MSComm1.Output = Chr(a)
MSComm1.Output = Chr(b)
Label1.Caption = 80
HScroll1.Value = 80
End Sub



xu3u4rmp4 該用戶已被刪除
2#
 樓主| 發表於 2011-8-19 20:20:55 | 只看該作者
忘了說 AVR程式中通訊部分還沒寫.會的人希望可以幫幫忙
我工作蠻忙的.而且隨時要收兵單了.所以不知道什麼時候才能完成.
3#
發表於 2011-8-20 08:11:15 | 只看該作者
第PORTC.2~PORTC.5不知道原因.信號輸出 << config fuse 的 jtagen 須關掉 ,它才能當一般i/o
PORTC = 0xFF; //m103 output only << m103 : 指的是Atmega103 這個IC
xu3u4rmp4 該用戶已被刪除
4#
 樓主| 發表於 2011-8-20 14:16:54 | 只看該作者
謝謝 問題解決了
xu3u4rmp4 該用戶已被刪除
5#
 樓主| 發表於 2011-8-23 01:09:03 | 只看該作者
請問一下
8051 KEIL-C中
串列資料可以直放入陣列中.
P[0]=SBUF;//將陣列P[0]裡的值改變
AVR 中似乎不能.請問是不是要加特別的指令呢?
unsigned char Uart_Receive(void)
{
  while (!(UCSRA & (1<<RXC)));
  return UDR;   
}
         
P[0]=Uart_Receive() ;
xu3u4rmp4 該用戶已被刪除
6#
 樓主| 發表於 2011-8-23 19:51:37 | 只看該作者
請問一下
我上面的主程式改成
void main(void)
{
init_devices();        
           while(1)
                {
                 unb=Uart_Receive();//接收馬達位置
                 PWM_in[unb]=Uart_Receive();//接收馬達PWM寬度
        }

}
VB傳送
Private Sub Command1_Click()
  Cmd_array = &H0'馬達位置
  MSComm1.Output = Chr(Cmd_array)
  Cmd_array = "150"馬達PWM寬度
  MSComm1.Output = Chr(Cmd_array)
End Sub

結果輸出寬度非1.5mS.而是小於0.8mS.說明了傳送錯誤
請問AVR中我把串列接收寫在主程式while(1){...};中.是否不對
7#
發表於 2011-8-29 16:50:07 | 只看該作者
小弟感覺樓主不用大費周章花時間搞avr,因為小弟無論從哪一角度看,這個都是一個標準的SSC-32電路。大大最好多花時間在vb就好。
xu3u4rmp4 該用戶已被刪除
8#
 樓主| 發表於 2011-8-29 19:41:13 | 只看該作者
AVR部分是給自己的作業.已經完成
VB部分編輯腳本部份完成.還差播放腳本功能就完成了
9#
發表於 2011-8-30 00:02:12 | 只看該作者
已回覆短消息。不過大大可能沒有興趣吧。
您需要登錄後才可以回帖 登錄 | 申請會員

本版積分規則

小黑屋|手機版|Archiver|機器人論壇 from 2005.07

GMT+8, 2024-4-28 23:34 , Processed in 0.181409 second(s), 10 queries , Apc On.

Powered by Discuz! X3.2

© 2001-2013 Comsenz Inc.

快速回復 返回頂部 返回列表