打印
[PIC®/AVR®/dsPIC®产品]

对 Arduino 感兴趣的这边看。

[复制链接]
楼主: MianQi
手机看帖
扫描二维码
随时随地手机跟帖
21
MianQi|  楼主 | 2022-9-1 10:35 | 只看该作者 回帖奖励 |倒序浏览
本帖最后由 MianQi 于 2022-9-1 10:47 编辑
zljiu 发表于 2022-9-1 09:34
请问什么叫做个人连载的形式呢

就是一个人不停地主说,其他人也说。

使用特权

评论回复
22
MianQi|  楼主 | 2022-9-1 10:42 | 只看该作者
aoyi 发表于 2022-9-1 09:04
请问基础校准应该怎么做呢

所谓“基础校准” - 选用官方推荐的商家出品的产品,在这里查,先用个3-5年,做上几十个项目,找到感觉了,知道了什么是正常的情况,能反推出异常的情况,然后,推而广之,着手其他的板型。

使用特权

评论回复
23
MianQi|  楼主 | 2022-9-1 10:43 | 只看该作者
tpgf 发表于 2022-9-1 08:44
这是一个很有意思的方向

对,很有意思。

使用特权

评论回复
24
MianQi|  楼主 | 2022-9-1 10:45 | 只看该作者
nawu 发表于 2022-9-1 09:27
这个用的是哪个芯片啊

最常见的是“ATMega328p”,双列直插封装,次常见的是“ATmega32U4”,平面四方型封装。

使用特权

评论回复
25
gwsan| | 2022-9-1 12:39 | 只看该作者
成本还是可以接受的

使用特权

评论回复
26
tfqi| | 2022-9-1 17:57 | 只看该作者
现在国产芯片在这方面用的也不错

使用特权

评论回复
27
MianQi|  楼主 | 2022-9-1 18:35 | 只看该作者
本帖最后由 MianQi 于 2022-9-2 09:06 编辑
gwsan 发表于 2022-9-1 12:39
成本还是可以接受的

Arduino 的特出之处不在于硬件,也不是软件,而是基于 Arduino 软硬件基础之上的这套生态系统——用例(创意)、教程、插件和扩展(移植)。

使用特权

评论回复
28
MianQi|  楼主 | 2022-9-10 16:23 | 只看该作者
Arduino UNO 基于 Atmel 的 ATmegA328 芯片,想要学 C 编程,就用这个工具 - https://www.nongnu.org/avr-libc/,想学汇编,就用这个工具 - https://www.microchip.com/en-us/ ... op/microchip-studio(原来的 Atmel Studio)。

使用特权

评论回复
29
Stahan| | 2022-9-10 22:36 | 只看该作者
Arduino 开发确实容易上手

使用特权

评论回复
评论
MianQi 2022-9-13 17:42 回复TA
Arduino 的特色之一是它的 API - 将一些对初学者来说较为困难的硬件特征和软件现象隐藏起来,使得初学者可以将全部注意力集中到C语言的语法规则和C程序的算法设计两方面来,尽快跨过门槛。接下来,我将通过一系列的示例来说明 Arduino 的这套 API。 
30
MianQi|  楼主 | 2022-9-13 17:47 | 只看该作者
示例一:Blink
代码是这样:
#define LED_BUILTIN 8

// the setup function runs once when you press reset or power the board
void setup() {
  // initialize digital pin LED_BUILTIN as an output.
  pinMode(LED_BUILTIN, OUTPUT);
}

// the loop function runs over and over again forever
void loop() {
  digitalWrite(LED_BUILTIN, HIGH);   // turn the LED on (HIGH is the voltage level)
  delay(1000);                       // wait for a second
  digitalWrite(LED_BUILTIN, LOW);    // turn the LED off by making the voltage LOW
  delay(1000);                       // wait for a second
}


运行效果是:Arduino UNO 板子上的 D8 到 GND 之间经限流电阻器(实测中用的是1.5kΩ)串联的 LED 以 0.5Hz 的频率亮灭变换。

使用特权

评论回复
31
MianQi|  楼主 | 2022-9-14 10:52 | 只看该作者
上述代码写成标准C的形式:
#include <util/delay.h>

int main(void)
{   
    // connect led to pin Arduino-D8/ATmega328p-PB0
    PB0_init();
  
    // loop forever
    while(1)
    {        
        PB0_toggle();
    }
}

void PB0_init(void){
  DDRB |= (1<<DDB0);
}

void PB0_toggle(void){
        PORTB ^= (1<<PORTB0); // toggles the led
        _delay_ms(1000);
}

使用特权

评论回复
32
MianQi|  楼主 | 2022-9-19 07:54 | 只看该作者
接下来,给 Arduino UNO 的 A0 脚上接一个电位器,用电位器调整 D8 脚上的 LED 的闪烁频率,用 Arduino C 表述,是这样:
/*
* The program for adjusting the LED blinking frequence by a potentiometer
* chip: ATmega328p
* potentiometer --> ADC0/A0(Arduino)
* (ATmega328p)PB0/D8(Arduino) --> 1.5kOhm --> LED
*/

int potVal = 0;
const int led = 8;

void setup(void){
  pinMode(A0, INPUT);
  pinMode(led, OUTPUT);
}
  
void loop(void)
{
  potVal = analogRead(A0);
  potVal = potVal/1023.0*500;  // Blinking frequence start from 1Hz

  ledBlink(potVal);
}

void ledBlink(int t){
  digitalWrite(led, HIGH);
  delay(t);
  digitalWrite(led, LOW);
  delay(t);
}

使用特权

评论回复
33
MianQi|  楼主 | 2022-9-21 07:33 | 只看该作者
本帖最后由 MianQi 于 2022-9-22 20:04 编辑

写成标准 C 的样子:
/*
* The program for adjusting the LED blinking frequency by a potentiometer
* chip: ATmega328p
* potentiometer --> ADC0
* (ATmega328p)PB0 --> 1.5kOhm --> LED
*/

#define F_CPU 16000000UL
#define VREF 5
#define POT 10000 // potentiometer - 10Kohm

#include <avr/io.h>
#include <avr/interrupt.h>
#include <util/delay.h>

volatile uint16_t potVal = 0;

void PB0_init();
void initADC();
uint16_t readADC(uint8_t);
  
int main(void)
{      
    // initialize ADC
    initADC();

    // LED connected to PB0/D8
    PB0_init();

    // loop forever
    while(1)
    {
      potVal = readADC(0);      
      PB0_toggle(potVal);
    }
}

void initADC()
{
  // Select V ref=AVcc
  // Bit 7:6 – REFS1:0: Reference Selection Bits
  // REFS1 REFS0 - 0 / 1 - AVCC with external capacitor at AREF pin
  ADMUX |= (1<<REFS0);

  // Bits 2:0 – ADPS2:0: ADC Prescaler Select Bits
  // These bits determine the division factor between the system clock frequency and the input clock to the ADC.
  //set prescaler to 128
  ADCSRA |= (1<<ADPS2)|(1<<ADPS1)|(1<<ADPS0);
  // Bit 7 – ADEN: ADC Enable - Writing this bit to one enables the ADC.
  ADCSRA |= (1<<ADEN);

  // Bit 6 – ADSC: ADC Start Conversion
  // The first conversion after ADSC has been written after the ADC has been enabled,
  // or if ADSC is written at the same time as the ADC is enabled,
  // will take 25 ADC clock cycles instead of the normal 13.
  // This first conversion performs initialization of the ADC.
  ADCSRA |= (1<<ADSC);
}

uint16_t readADC(uint8_t ADCchannel)
{
  //select ADC channel with safety mask
  ADMUX = (ADMUX & 0xF0) | (ADCchannel & 0x0F);

  // A single conversion is started by disabling the power reduction ADC bit, PRADC, by writing a logical zero to it
  // and writing a logical one to the ADC start conversion bit, ADSC.
  ADCSRA |= (1<<ADSC);
   
  // wait until ADC conversion is complete
  while( ADCSRA & (1<<ADSC) );
  
  return ADC;
}

void PB0_init(void){
   DDRB |= (1<<DDB0);
}

void PB0_toggle(int t){
   PORTB ^= (1<<PORTB0); // toggles the led
   for(int i = 0; i < t; i++){
     _delay_ms(1);
   }
}



使用特权

评论回复
34
MianQi|  楼主 | 2022-9-23 19:03 | 只看该作者
做完了 Blink,再做一个 Fade,就是通常所说的呼吸灯。因为要用到 PWM 输出功能,所以,LED 要从 D8 换到 D9,因为Arduino UNO 具备 PWM 功能的管脚位于:D3,D5,D6,D9,D10,D11。
实验过程是这样:通过一个外接到 A0 脚的电位器调节连接到 D9 脚的 LED 的亮度。
Arduino 代码是这样:
/*
  Fade

  This example shows how to fade an LED on pin 9 using the analogWrite()
  function through a potentiometer connected to A0.

  The analogWrite() function uses PWM, so if you want to change the pin you're
  using, be sure to use another PWM capable pin. On most Arduino, the PWM pins
  are identified with a "~" sign, like ~3, ~5, ~6, ~9, ~10 and ~11.
*/

const int led = 9;           // the PWM pin the LED is attached to
const int pot = A0;         // the ADC0 channel connected to potentiometer

int brightness = 0;    // how bright the LED is
int fadeAmount = 0;    // how many points to fade the LED by potentiometer


// the setup routine runs once when you press reset:
void setup() {
  // declare pin 9 to be an output:
  pinMode(led, OUTPUT);
  pinMode(pot, INPUT);

  // for debugging:
  Serial.begin(115200);
}

// the loop routine runs over and over again forever:
void loop() {
  // read the potentiometer from A0:
  fadeAmount = analogRead(pot);
  
  // map the value from 0-1023 to 0-255:
  brightness = map(fadeAmount, 0, 1023, 0, 255);
  
  // set the brightness of pin 9:
  analogWrite(led, brightness);
  
  // show the PWM value on Serial Monitor:
  Serial.print("Current PWM: ");
  Serial.println(brightness);
  
  // wait for 30 milliseconds to see the dimming effect
  delay(30);
}

使用特权

评论回复
35
littlelida| | 2022-10-2 15:08 | 只看该作者
呦呵,太秀了~~~漂亮

使用特权

评论回复
36
MianQi|  楼主 | 2022-10-5 08:13 | 只看该作者
本帖最后由 MianQi 于 2022-10-5 12:11 编辑

上述 Arduino C 写成 avr-libc 就是这样:
/*
* The program for adjusting the lightness of LED by a potentiometer
* chip: ATmega328p
* potentiometer --> ADC0
* (ATmega328p)PB1 --> 1.5kOhm --> LED
*/

#define F_CPU 16000000UL
#define VREF 5
#define POT 10000 // potentiometer - 10Kohm

#include <avr/io.h>
#include <util/delay.h>

void timer1_init();
void initADC();
uint16_t readADC(uint8_t);
void promptPrint(void);

volatile uint16_t potVal = 0;
unsigned char helloworld[] = "potValue = ";

int main(void){
  
  // LED 接在: OC1A/ATmega328p PB1/Arduino UNO D9
    DDRB |= (1<<DDB1);
  // ADC 初始化
    initADC();
  // 初始化定时器1(16位)
    timer1_init();
  // 初始化串口
    USART0_init();
  // 开全局中断
   
    while(1) {
  // ADC 读入
    potVal = readADC(0);
    OCR1A = (potVal/1023.0)*250;
  // 串口显示
    promptPrint();
    regToDigitAndTransmit(potVal);
    }
}

void timer1_init(){
  // OC1A 正向输出
    TCCR1A = (1 << COM1A1);
  // 模式14
    TCCR1A |= (1 << WGM11);
    TCCR1B |= (1 << WGM13)|(1 << WGM12);
  // 预分频64 - frequency = 250kHz
    TCCR1B |= (1 << CS11)|(1 << CS10);
  // ICR1 作为置顶值
    ICR1 = 250;
  // OCR1A 初值:
    OCR1A = 3;
  // TCNT1 初值:
    TCNT1 = 0;
}

void initADC()
{
  // Select V ref=AVcc
  // Bit 7:6 – REFS1:0: Reference Selection Bits
  // REFS1 REFS0 - 0 / 1 - AVCC with external capacitor at AREF pin
  ADMUX |= (1<<REFS0);

  // Bits 2:0 – ADPS2:0: ADC Prescaler Select Bits
  // These bits determine the division factor between the system clock frequency and the input clock to the ADC.
  //set prescaler to 128
  ADCSRA |= (1<<ADPS2)|(1<<ADPS1)|(1<<ADPS0);
  // Bit 7 – ADEN: ADC Enable - Writing this bit to one enables the ADC.
  ADCSRA |= (1<<ADEN);
  // Bit 6 – ADSC: ADC Start Conversion
  // The first conversion after ADSC has been written after the ADC has been enabled,
  // or if ADSC is written at the same time as the ADC is enabled,
  // will take 25 ADC clock cycles instead of the normal 13.
  // This first conversion performs initialization of the ADC.
  ADCSRA |= (1<<ADSC);
}

uint16_t readADC(uint8_t ADCchannel)
{
  //select ADC channel with safety mask
  ADMUX = (ADMUX & 0xF0) | (ADCchannel & 0x0F);

  // A single conversion is started by disabling the power reduction ADC bit, PRADC, by writing a logical zero to it
  // and writing a logical one to the ADC start conversion bit, ADSC.
  ADCSRA |= (1<<ADSC);
   
  // wait until ADC conversion is complete
  while( ADCSRA & (1<<ADSC) );
  
  return ADC;
}

void promptPrint(void){
  for(int i = 0; i < sizeof(helloworld); i++){
    TX(helloworld[i]);   //echo back the received byte to the computer
  }
  _delay_ms(100);  
}

void USART0_init(void) {
    UCSR0A = B00000000; //single transmission speed, multiprocessor disabled
    UCSR0B = B00011000; //enable Rx & Tx
    UCSR0C = B00000110; //asynchronous, no parity, 1 stop, 8 bits
    UBRR0 = 103;        //load the value for 9600 bps baud rate into whole UBRR register
}

void TX(unsigned char TXData) {
    //do nothing until UDR0 is ready for more data to be written to it; wait for USART UDRE flag
    while ((UCSR0A & (1 << UDRE0)) == 0) {};
    //when flag is set send data by placing the byte into UDR0
    UDR0 = TXData;
}

void TXstring(char* str) {
    while(*str) {
        TX(*str++);
    }
    TX('.');
    TX('\n');
}

unsigned char regToDigitAndTransmit(uint16_t valueADC){
    char buff[8];
    itoa(valueADC, buff, 10);
   //sprintf(buff, "%u.%02u", valueADC / 100, valueADC % 100);
    TXstring(buff);
}


这就是体现了“Arduino 向初学者隐藏了嵌入式C编程的一些令人困惑的细节,从而使得初学者可以将注意力集中在熟悉C语言的语法规则、项目本身的工程思路和算法设计上”。

使用特权

评论回复
37
weifeng90| | 2022-10-5 17:25 | 只看该作者
arduino都忘的差不多了

使用特权

评论回复
38
Undshing| | 2022-10-10 21:00 | 只看该作者
arduino方便但是好像没见过有用来做产品的

使用特权

评论回复
39
MianQi|  楼主 | 2022-10-11 08:11 | 只看该作者
1. 大一点的:
ArduPilot - Versatile, Trusted, Open
2. 小一点的:
AR6C

使用特权

评论回复
40
MianQi|  楼主 | 2022-10-15 17:18 | 只看该作者
本帖最后由 MianQi 于 2022-10-24 18:38 编辑

接下来,我要演示的是两个 Arduino UNO 之间的 IIC 通信。在 UNO 板子上,SDA 和 SCL 的管脚分别复用在 A4 和 A5 管脚,也可以用 AREF 外侧的两个管脚,这两个管脚是 A4 和 A5 的延申。

两块 Arduino UNO 之间的接线是这样:
SDA - SDA
SCL - SCL
GND - GND

要实现的效果是:用一个 UNO 上接着的电位器调节另一个 UNO 上接着的 LED闪烁频率。

使用特权

评论回复
发新帖 我要提问
您需要登录后才可以回帖 登录 | 注册

本版积分规则