Pagina's

2022/02/20

Arduino UNO DS1302


On my pc the Arduino ide uses port "COM3" to program a UNO.
A C# program uses the same port.
Button1 writes the pc date/time to the DS1302,
Button2 reads date/time from the DS1302, it is written to label1.
When the port is disconnected, the DS1302 keeps the time with a CR2032 backup battery.
If the port is connected again the proper time can be read by clicking button2 (two times:)

ARDUINO code (2446 bytes (7%), 192 bytes (9%)):

void
setup() {
  Serial.begin(9600);
  while (!Serial);
  pinMode(13, OUTPUT); // Led off             // Vcc2 -|1    8|- Vcc1
  pinMode(7, OUTPUT);  // Clock           c   //     X1 -|2    7|- SCLK
  pinMode(6, OUTPUT);  // Data (I/O)    w  //     X2 -|3    6|- I/O
  pinMode(5, OUTPUT);  // Enable         e  //  GND -|4    5|- CE
  c(0); h(); e(0); h();                                     //           DS1302
}

byte b[8];

void loop() {
  io(1);  byte com[1]; // command
  Serial.readBytes(com, 1);
  if (com [0] == 0) {           // pc date time -> DS1302
    setup();
    Serial.readBytes(b, 7);
    c(0); h(); e(0); h(); io(0); h(); e(1); h();
    w(0xBE);
    for (int i = 0; i < 8; i++)  w(b[i]);
    e(0); c(0);
  }
  else {                        // DS1302 -> label1
    c(0); h(); e(0); h(); io(0); h(); e(1); h();
    w(0xBF); io(1);
    for (int i = 0; i < 8; i++) b[i] = r();
    e(0); c(0);
    Serial.write(b, 7);
  }
}

void io(byte io) {
  if (io > 0)pinMode(6, INPUT); else pinMode(6, OUTPUT); h();
}
byte r() {
  byte r = 0;
  for (int i = 0; i < 8; i++)  {
    c(0); r |= digitalRead(6) << i; c(1);
  }
  return r;
}
void w(byte w) {
  for (int i = 0; i < 8; i++) {
    c(0); if (w & 1 > 0)digitalWrite(6, HIGH); else digitalWrite(6, LOW); w >>= 1; c(1);
  }
}
void c(byte c) {
  if (c > 0)digitalWrite(7, HIGH); else digitalWrite(7, LOW); h();
}
void e(byte e) {
  if (e > 0)digitalWrite(5, HIGH); else digitalWrite(5, LOW); h();
}
void h() {
  delayMicroseconds(1);
}

C# code:
using System;
using System.IO.Ports;
using System.Windows.Forms;
namespace DS1302_02
{
    public partial class Form1 : Form
    {
        public Form1() { InitializeComponent(); }
 
        private void button1_Click(object sender, EventArgs e)
        {                                 // pc date time -> DS1302
            button1.Enabled = false;
            button2.Focus();
            var sp = new SerialPort("COM3");
            sp.BaudRate = 9600; sp.Open();
            sp.Write(new byte[] { 0 }, 0, 1);
            var DT = DateTime.Now.AddSeconds(1);
            var b = new byte[8];
            b[6] = (byte)(DT.Year % 100);
            b[5] = (byte)(DT.DayOfWeek); if (b[5] == 0) b[5] = 7;
            b[4] = (byte)(DT.Month);
            b[3] = (byte)(DT.Day);
            b[2] = (byte)(DT.Hour);
            b[1] = (byte)(DT.Minute);
            b[0] = (byte)(DT.Second);
            for (int i = 0; i < 8; i++)
                b[i] = (byte)(b[i] % 10 | b[i] / 10 << 4);
            sp.Write(b, 0, 8); sp.Close();
            System.Threading.Thread.Sleep(1050);
            this.button2_Click(sender, e);
        }
 
        private void button2_Click(object sender, EventArgs e)
        {                                 // DS1302 -> label1
            button2.Enabled = false;
            var sp = new SerialPort("COM3");
            sp.BaudRate = 9600; sp.Open();
            var b = new byte[8];
        L0: sp.Write(new byte[] { 1 }, 0, 1);
            int c = 0;
            while (sp.BytesToRead < 8)
                if (c++ > 2)
                {
                    sp.ReadExisting();
                    goto L0;
                }
            for (int i = 0; i < 8; i++)
                b[i] = (byte)sp.ReadByte();
            sp.ReadExisting(); sp.Close();
            label1.Text = (b[6] >> 4).ToString() + (b[6] & 15).ToString() + " ";
            for (int i = 4; i >= 0; i--)
                label1.Text += (b[i] >> 4).ToString() + (b[i] & 15).ToString() + " ";
            label1.Text += "  " + b[5].ToString();
            button1.Enabled = true;
            button2.Enabled = true;
            button2.Focus();
        }
    }
}